aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/msc/msc_a.h3
-rw-r--r--src/libmsc/gsm_04_08.c36
2 files changed, 39 insertions, 0 deletions
diff --git a/include/osmocom/msc/msc_a.h b/include/osmocom/msc/msc_a.h
index a4d3226ed..18973f9af 100644
--- a/include/osmocom/msc/msc_a.h
+++ b/include/osmocom/msc/msc_a.h
@@ -99,6 +99,9 @@ struct msc_a {
/* After Ciphering Mode Complete on GERAN, this reflects the chosen ciphering algorithm and key */
struct geran_encr geran_encr;
+ /* Type of MI requested in MM Identity Request */
+ uint8_t mm_id_req_type;
+
/* N(SD) expected in the received frame, per flow (TS 24.007 11.2.3.2.3.2.2) */
uint8_t n_sd_next[4];
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index 750c76651..b284ccd7a 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -182,6 +182,7 @@ static int mm_rx_id_resp(struct msc_a *msc_a, struct msgb *msg)
struct gsm48_hdr *gh = msgb_l3(msg);
uint8_t *mi = gh->data+1;
uint8_t mi_len = gh->data[0];
+ uint8_t mi_type;
struct vlr_subscr *vsub = msc_a_vsub(msc_a);
if (!vsub) {
@@ -190,6 +191,28 @@ static int mm_rx_id_resp(struct msc_a *msc_a, struct msgb *msg)
return -EINVAL;
}
+ /* There muct be at least one octet with MI type */
+ if (!mi_len) {
+ LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains "
+ "malformed Mobile Identity\n");
+ return -EINVAL;
+ }
+
+ /* Make sure we got what we expected */
+ mi_type = mi[0] & GSM_MI_TYPE_MASK;
+ if (mi_type == GSM_MI_TYPE_NONE) {
+ LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains no identity, "
+ "perhaps the MS has no Mobile Identity type %s?\n",
+ gsm48_mi_type_name(msc_a->mm_id_req_type));
+ return -EINVAL;
+ } else if (mi_type != msc_a->mm_id_req_type) {
+ LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains unexpected "
+ "Mobile Identity type %s (extected %s)\n",
+ gsm48_mi_type_name(mi_type),
+ gsm48_mi_type_name(msc_a->mm_id_req_type));
+ return -EINVAL;
+ }
+
DEBUGP(DMM, "IDENTITY RESPONSE: MI=%s\n", osmo_mi_name(mi, mi_len));
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data);
@@ -1182,8 +1205,17 @@ static int gsm48_rx_rr_ciphering_mode_complete(struct msc_a *msc_a, struct msgb
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
mi = TLVP_GET(&tp, GSM48_IE_MOBILE_ID);
+ /* IMEI(SV) is optional for this message */
if (!mi)
return 0;
+ if (!mi->len)
+ return -EINVAL;
+ if ((mi->val[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMEISV) {
+ LOGP(DMM, LOGL_ERROR, "RR Ciphering Mode Complete contains "
+ "unexpected Mobile Identity type %s\n",
+ gsm48_mi_type_name(mi->val[0] & GSM_MI_TYPE_MASK));
+ return -EINVAL;
+ }
LOG_MSC_A(msc_a, LOGL_DEBUG, "RR Ciphering Mode Complete contains Mobile Identity: %s\n",
osmo_mi_name(mi->val, mi->len));
@@ -1287,6 +1319,10 @@ static int msc_vlr_tx_auth_rej(void *msc_conn_ref)
static int msc_vlr_tx_id_req(void *msc_conn_ref, uint8_t mi_type)
{
struct msc_a *msc_a = msc_conn_ref;
+
+ /* Store requested MI type, so we can check the response */
+ msc_a->mm_id_req_type = mi_type;
+
return mm_tx_identity_req(msc_a, mi_type);
}