<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-msc/+/16683">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libmsc/gsm_04_08.c: fix: verify MI before calling vlr_subscr_rx_id_resp()<br><br>During the last congress, we have noticed that OsmoMSC crashes<br>on receipt of malformed MM Identity Response messages:<br><br>  BSSAP<br>      Message Type: Direct Transfer (0x01)<br>      Data Link Connection Identifier<br>          00.. .... = Control Channel: not further specified (0x0)<br>          ..00 0... = Spare: 0x0<br>          .... .000 = SAPI: RR/MM/CC (0x0)<br>      Length: 11<br>  GSM A-I/F DTAP - Identity Response<br>      Protocol Discriminator: Mobility Management messages (5)<br>          .... 0101 = Protocol discriminator: Mobility Management messages (0x5)<br>          0000 .... = Skip Indicator: No indication of selected PLMN (0)<br>      01.. .... = Sequence number: 1<br>      ..01 1001 = DTAP Mobility Management Message Type: Identity Response (0x19)<br>      Mobile Identity - Format Unknown<br>          Length: 8<br>          .... 1... = Odd/even indication: Odd number of identity digits<br>          .... .111 = Mobile Identity Type: Unknown (7)  <-- This makes OsmoMSC crash<br>              [Expert Info (Warning/Protocol): Unknown format 7]<br>                  [Unknown format 7]<br>                  [Severity level: Warning]<br>                  [Group: Protocol]<br><br>The value '111'B is not a valid Mobile Identity type, and shall be<br>considered as reserved according to 3GPP TS 24.008, section 10.5.1.4.<br>Later on it was discovered that '000'B also crashes OsmoMSC in the same way.<br><br>The crash itself is provoked by OSMO_ASSERT(0) in vlr_subscr_rx_id_resp().<br>Let's keep that assert in there, and make sure that:<br><br>  - on receipt of MM Identity Response, Mobile Identity type<br>    matches the one in MM Identity Request;<br><br>  - on receipt of RR Ciphering Mode Complete, Mobile Identity<br>    contains IMEI(SV) if present.<br><br>Change-Id: Ica4c90b8eb4d90325313c6eb400fa4a6bc5df825<br>TTCN-3 test case: I62f23355eb91df2edf9dc837c928cb86b530b743<br>Fixes: OS#4340<br>---<br>M include/osmocom/msc/msc_a.h<br>M src/libmsc/gsm_04_08.c<br>2 files changed, 39 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/msc_a.h b/include/osmocom/msc/msc_a.h</span><br><span>index a4d3226..18973f9 100644</span><br><span>--- a/include/osmocom/msc/msc_a.h</span><br><span>+++ b/include/osmocom/msc/msc_a.h</span><br><span>@@ -99,6 +99,9 @@</span><br><span>  /* After Ciphering Mode Complete on GERAN, this reflects the chosen ciphering algorithm and key */</span><br><span>   struct geran_encr geran_encr;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     /* Type of MI requested in MM Identity Request */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t mm_id_req_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* N(SD) expected in the received frame, per flow (TS 24.007 11.2.3.2.3.2.2) */</span><br><span>      uint8_t n_sd_next[4];</span><br><span> </span><br><span>diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c</span><br><span>index 750c766..b284ccd 100644</span><br><span>--- a/src/libmsc/gsm_04_08.c</span><br><span>+++ b/src/libmsc/gsm_04_08.c</span><br><span>@@ -182,6 +182,7 @@</span><br><span>         struct gsm48_hdr *gh = msgb_l3(msg);</span><br><span>         uint8_t *mi = gh->data+1;</span><br><span>         uint8_t mi_len = gh->data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t mi_type;</span><br><span>     struct vlr_subscr *vsub = msc_a_vsub(msc_a);</span><br><span> </span><br><span>     if (!vsub) {</span><br><span>@@ -190,6 +191,28 @@</span><br><span>          return -EINVAL;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* There muct be at least one octet with MI type */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!mi_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains "</span><br><span style="color: hsl(120, 100%, 40%);">+                                    "malformed Mobile Identity\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Make sure we got what we expected */</span><br><span style="color: hsl(120, 100%, 40%);">+       mi_type = mi[0] & GSM_MI_TYPE_MASK;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (mi_type == GSM_MI_TYPE_NONE) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains no identity, "</span><br><span style="color: hsl(120, 100%, 40%);">+                                       "perhaps the MS has no Mobile Identity type %s?\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 gsm48_mi_type_name(msc_a->mm_id_req_type));</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else if (mi_type != msc_a->mm_id_req_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains unexpected "</span><br><span style="color: hsl(120, 100%, 40%);">+                                 "Mobile Identity type %s (extected %s)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                  gsm48_mi_type_name(mi_type),</span><br><span style="color: hsl(120, 100%, 40%);">+                                  gsm48_mi_type_name(msc_a->mm_id_req_type));</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  DEBUGP(DMM, "IDENTITY RESPONSE: MI=%s\n", osmo_mi_name(mi, mi_len));</span><br><span> </span><br><span>   osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data);</span><br><span>@@ -1182,8 +1205,17 @@</span><br><span>    tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);</span><br><span>   mi = TLVP_GET(&tp, GSM48_IE_MOBILE_ID);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       /* IMEI(SV) is optional for this message */</span><br><span>  if (!mi)</span><br><span>             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!mi->len)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((mi->val[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMEISV) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DMM, LOGL_ERROR, "RR Ciphering Mode Complete contains "</span><br><span style="color: hsl(120, 100%, 40%);">+                                      "unexpected Mobile Identity type %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                     gsm48_mi_type_name(mi->val[0] & GSM_MI_TYPE_MASK));</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span>        LOG_MSC_A(msc_a, LOGL_DEBUG, "RR Ciphering Mode Complete contains Mobile Identity: %s\n",</span><br><span>            osmo_mi_name(mi->val, mi->len));</span><br><span>@@ -1287,6 +1319,10 @@</span><br><span> static int msc_vlr_tx_id_req(void *msc_conn_ref, uint8_t mi_type)</span><br><span> {</span><br><span>  struct msc_a *msc_a = msc_conn_ref;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Store requested MI type, so we can check the response */</span><br><span style="color: hsl(120, 100%, 40%);">+   msc_a->mm_id_req_type = mi_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        return mm_tx_identity_req(msc_a, mi_type);</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-msc/+/16683">change 16683</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-msc/+/16683"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-msc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ica4c90b8eb4d90325313c6eb400fa4a6bc5df825 </div>
<div style="display:none"> Gerrit-Change-Number: 16683 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>