aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-05-15 23:52:21 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-05-15 23:55:28 +0800
commit45bb8bfc1a14676bd6c599eff7980bc3f141f99e (patch)
tree5b91b1c92790c06a39cbad5f88089e2864630c61 /openbsc
parent57900f00088e99731ad0d22cb1701eaa22cc25f0 (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.h2
-rw-r--r--openbsc/src/bsc_msc_ip.c9
-rw-r--r--openbsc/src/gsm_04_08.c5
-rw-r--r--openbsc/src/gsm_04_08_utils.c17
4 files changed, 25 insertions, 8 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index eb445d11a..5c4c62889 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -45,7 +45,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/bsc_msc_ip.c b/openbsc/src/bsc_msc_ip.c
index bfd9138ee..34e4fe34d 100644
--- a/openbsc/src/bsc_msc_ip.c
+++ b/openbsc/src/bsc_msc_ip.c
@@ -365,7 +365,14 @@ static int handle_paging_response(struct msgb *msg)
char mi_string[GSM48_MI_SIZE];
u_int8_t mi_type;
- gsm48_paging_extract_mi(msg, mi_string, &mi_type);
+ struct gsm48_hdr *hdr;
+ struct gsm48_pag_resp *resp;
+
+ hdr = msgb_l3(msg);
+ resp = (struct gsm48_pag_resp *) &hdr->data[0];
+
+ gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*hdr),
+ mi_string, &mi_type);
LOGP(DMSC, LOGL_DEBUG, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
mi_type, mi_string);
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 17457736a..c98643883 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -779,13 +779,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 e51faba82..be26aa36c 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -285,13 +285,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);
}