aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chemeris <Alexander.Chemeris@gmail.com>2013-07-03 10:12:23 +0400
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-07-04 18:34:49 +0200
commit84402c0c82e0ff9591c760485e0790cf658aef91 (patch)
treea4e39635584e40f3797c5b67bf3d038a7ff328bd
parentf0167ddfc26755ef44be5c6939b3491e3364ba36 (diff)
sgsn: Fix lengths of MS Network Capability and MS Radio Access Capability elements.
Original code was inconsistent about lengths and could lead to out of bounds write. Lengths were also inconsistent with the TS 24.008. Fixes: Coverity CID 1040714.
-rw-r--r--openbsc/include/openbsc/gprs_sgsn.h4
-rw-r--r--openbsc/src/gprs/gprs_gmm.c7
2 files changed, 5 insertions, 6 deletions
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 6a653b7fe..8074d8f9b 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -80,12 +80,12 @@ struct sgsn_mm_ctx {
/* CKSN */
enum gprs_ciph_algo ciph_algo;
struct {
- uint8_t buf[52]; /* 10.5.5.12a */
uint8_t len;
+ uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */
} ms_radio_access_capa;
struct {
- uint8_t buf[4]; /* 10.5.5.12 */
uint8_t len;
+ uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */
} ms_network_capa;
uint16_t drx_parms;
int mnrg; /* MS reported to HLR? */
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 72d9e764b..bb61ab50a 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -648,7 +648,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
/* MS network capability 10.5.5.12 */
msnc_len = *cur++;
msnc = cur;
- if (msnc_len > 8)
+ if (msnc_len > sizeof(ctx->ms_network_capa.buf))
goto err_inval;
cur += msnc_len;
@@ -679,7 +679,7 @@ 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 > 52)
+ if (ms_ra_acc_cap_len > sizeof(ctx->ms_radio_access_capa.buf))
goto err_inval;
cur += ms_ra_acc_cap_len;
@@ -740,8 +740,7 @@ 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 = OSMO_MIN(ms_ra_acc_cap_len,
- sizeof((ctx->ms_radio_access_capa.buf)));
+ ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len;
memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap,
ctx->ms_radio_access_capa.len);
ctx->ms_network_capa.len = msnc_len;