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.
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 6a653b7..8074d8f 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -80,12 +80,12 @@
/* 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 72d9e76..bb61ab5 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -648,7 +648,7 @@
/* 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 @@
/* 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 @@
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;