diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-05-16 01:51:14 +0800 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-05-16 01:51:14 +0800 |
commit | f6903dee891e4e6d7853e35c6fdca22c78559225 (patch) | |
tree | 53b8302beb597606c3a0b3c343a25ef5567e209d /openbsc | |
parent | 5d65806472594ecb3f8d4808e311a9d0271fb086 (diff) |
gsm48: Add size checks to the paging response mi parsing.
We go from no size checks to some content checking. We should
refactor the whole classmark2 + mi parsing that is used throughout
the code into one place with proper size checking. This is the
start and requires a new libosmocore as well.
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/gsm_04_08.h | 2 | ||||
-rw-r--r-- | openbsc/src/gsm_04_08.c | 5 | ||||
-rw-r--r-- | openbsc/src/gsm_04_08_utils.c | 17 |
3 files changed, 17 insertions, 7 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 74dcbe52a..a49f91ed6 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -52,7 +52,7 @@ int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv, int h_len); int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv); -int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type); +int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, u_int8_t *mi_type); int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr); int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode); diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index eecf76ff0..06e19ac0a 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -785,13 +785,16 @@ static int gsm48_rx_rr_pag_resp(struct msgb *msg) { struct gsm_bts *bts = msg->lchan->ts->trx->bts; struct gsm48_hdr *gh = msgb_l3(msg); + struct gsm48_pag_resp *resp; u_int8_t *classmark2_lv = gh->data + 1; u_int8_t mi_type; char mi_string[GSM48_MI_SIZE]; struct gsm_subscriber *subscr = NULL; int rc = 0; - gsm48_paging_extract_mi(msg, mi_string, &mi_type); + resp = (struct gsm48_pag_resp *) &gh->data[0]; + gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh), + mi_string, &mi_type); DEBUGP(DRR, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n", mi_type, mi_string); diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c index 1b3ed2537..db8c3a5e4 100644 --- a/openbsc/src/gsm_04_08_utils.c +++ b/openbsc/src/gsm_04_08_utils.c @@ -243,13 +243,20 @@ int send_siemens_mrpci(struct gsm_lchan *lchan, return rsl_siemens_mrpci(lchan, &mrpci); } -int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type) +int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length, + char *mi_string, u_int8_t *mi_type) { - struct gsm48_hdr *gh = msgb_l3(msg); - u_int8_t *classmark2_lv = gh->data + 1; - u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv; - *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; + u_int8_t *classmark2_lv = (uint8_t *) &resp->classmark2; + /* Check the size for the classmark */ + if (length < 2 + *classmark2_lv) + return -1; + + u_int8_t *mi_lv = classmark2_lv + *classmark2_lv + 1; + if (length < 3 + *classmark2_lv + mi_lv[0]) + return -2; + + *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv); } |