summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-07-27 23:35:38 +0200
committerHarald Welte <laforge@gnumonks.org>2011-07-27 23:35:38 +0200
commit4b2ed35b8f35b86ad19e9ff12485dba8adc26e50 (patch)
tree87f49f997ff1ee1668724be51195d8f7e5537f99
parent074b2b24e00fa4f6e39e2f5025ec628663ac95d8 (diff)
GPRS: Fix buffer overflow in case of very long MS RA CAP IE
The MS Radio Access Capability IE can be _very_ long in some recent high-end mobile phones, way beyond the old 14-byte limit. We increase our array to 52 bytes, and make sure not to overflow that buffer.
-rw-r--r--openbsc/include/openbsc/gprs_sgsn.h2
-rw-r--r--openbsc/src/gprs/gprs_gmm.c12
2 files changed, 10 insertions, 4 deletions
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 5023d0684..62fbb85a5 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -78,7 +78,7 @@ struct sgsn_mm_ctx {
/* CKSN */
enum gprs_ciph_algo ciph_algo;
struct {
- uint8_t buf[14]; /* 10.5.5.12a */
+ uint8_t buf[52]; /* 10.5.5.12a */
uint8_t len;
} ms_radio_access_capa;
struct {
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 7eff33f5f..098e4c25b 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -675,8 +675,9 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
/* MS Radio Access Capability 10.5.5.12a */
ms_ra_acc_cap_len = *cur++;
ms_ra_acc_cap = cur;
- if (ms_ra_acc_cap_len > 51)
+ if (ms_ra_acc_cap_len > 52)
goto err_inval;
+ cur += ms_ra_acc_cap_len;
/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */
@@ -735,8 +736,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
ctx->cell_id = cid;
/* Update MM Context with other data */
ctx->drx_parms = drx_par;
- ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len;
- memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap, ms_ra_acc_cap_len);
+ ctx->ms_radio_access_capa.len = OSMO_MIN(ms_ra_acc_cap_len,
+ sizeof((ctx->ms_radio_access_capa.buf)));
+ memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap,
+ ctx->ms_radio_access_capa.len);
ctx->ms_network_capa.len = msnc_len;
memcpy(ctx->ms_network_capa.buf, msnc, msnc_len);
@@ -910,6 +913,9 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
/* MS Radio Access Capability 10.5.5.12a */
ms_ra_acc_cap_len = *cur++;
ms_ra_acc_cap = cur;
+ if (ms_ra_acc_cap_len > 52)
+ return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_PROTO_ERR_UNSPEC);
+ cur += ms_ra_acc_cap_len;
/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status,
* DRX parameter, MS network capability */