aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2019-08-29 00:10:49 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2019-09-18 15:31:13 +0200
commite9a39118448e4e6f50f2f1ec579a1b6f5ab5434e (patch)
tree9c55ae6e61743a589dbbbc82293e3ad5462b87d9
parenteb1b03a98adbb506620c3adc11114691b54266f7 (diff)
fix error on BSSMAP Cipher Mode Complete L3 msg IE
When an MS returns the IMEISV in the BSSMAP Cipher Mode Complete message in the Layer 3 Message Contents IE, do not re-invoke the decode_cb() a second time, but instead point to it from the ran_msg.cipher_mode_complete struct. When the MSC-A decodes the Ciphering Mode Complete message, it always wants to also decode the enclosed DTAP from the Layer 3 Message Contents IE. However, when the MSC-I preliminarily decodes messages, it often just wants to identify specific messages without fully acting on them, let alone dispatching RAN_UP_L2 events more than once. So leave it up to the supplied decode_cb passed to ran_dec_l2() implementations to decide whether to decode the DTAP. In msc_a.c hence evaluate the DTAP by passing a msgb to msc_a_up_l3(), which will evaluate the RR Ciphering Mode Complete message found in the BSSMAP Cipher Mode Complete's Layer 3 Message Contents IE. Particularly, the previous choice of calling the decode_cb a second time for the enclosed DTAP caused a header/length parsing error: the second decode_cb call tried to mimick DTAP by overwriting the l3h pointer and truncating the length of the msgb, but subsequently ran_a_decode_l2() would again derive the l3h from the l2h, obliterating the intended re-interpretation as DTAP, and hence the previous truncation caused error messages on each and every Cipher Mode Complete message, like: DBSSAP ERROR libmsc/ran_msg_a.c:764 msc_a(IMSI-26242340300XXXX:MSISDN-XXXX:TMSI-0xA73E055A:GERAN-A-77923:LU)[0x5563947521e0]{MSC_A_ST_AUTH_CIPH}: RAN decode: BSSMAP: BSSMAP data truncated, discarding message This error was seen a lot at CCCamp2019. Modifying the msgb was a bad idea to begin with, the approach taken in this patch is much cleaner. Note that apparently many phones include the IMEISV in the Cipher Mode Complete message even though the BSSMAP Cipher Mode Command did not include the Cipher Response Mode IE. So, even though we did not specifically ask for the Cipher Mode Complete to include any identity, many MS default to including the IMEISV of their own accord. Reproduce: attach to osmo-msc with ciphering enabled using a Samsung Galaxy S4mini. Related: OS#4168 Change-Id: Icd8dad18d6dda24d075dd8da72c3d6db1302090d
-rw-r--r--include/osmocom/msc/ran_msg.h1
-rw-r--r--src/libmsc/msc_a.c12
-rw-r--r--src/libmsc/ran_msg_a.c14
3 files changed, 16 insertions, 11 deletions
diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index af0822b70..081c7ad4d 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -210,6 +210,7 @@ struct ran_msg {
* alg_id == 0 means no such IE was present. */
uint8_t alg_id;
const char *imeisv;
+ const struct tlv_p_entry *l3_msg;
} cipher_mode_complete;
struct {
enum gsm0808_cause bssap_cause;
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index b41457458..344b442cb 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -1407,6 +1407,18 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
};
vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_COMPL);
rc = 0;
+
+ /* Evaluate enclosed L3 message, typically Identity Response (IMEISV) */
+ if (msg->cipher_mode_complete.l3_msg) {
+ unsigned char *data = (unsigned char*)(msg->cipher_mode_complete.l3_msg->val);
+ uint16_t len = msg->cipher_mode_complete.l3_msg->len;
+ struct msgb *dtap = msgb_alloc(len, "DTAP from Cipher Mode Complete");
+ unsigned char *pos = msgb_put(dtap, len);
+ memcpy(pos, data, len);
+ dtap->l3h = pos;
+ rc = msc_a_up_l3(msc_a, dtap);
+ msgb_free(dtap);
+ }
break;
case RAN_MSG_CIPHER_MODE_REJECT:
diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c
index 43e27f6ca..7672d863d 100644
--- a/src/libmsc/ran_msg_a.c
+++ b/src/libmsc/ran_msg_a.c
@@ -194,18 +194,10 @@ static int ran_a_decode_cipher_mode_complete(struct ran_dec *ran_dec, struct msg
ran_dec_msg.cipher_mode_complete.alg_id = ie_chosen_encr_alg->val[0];
}
- rc = ran_decoded(ran_dec, &ran_dec_msg);
+ if (ie_l3_msg)
+ ran_dec_msg.cipher_mode_complete.l3_msg = ie_l3_msg;
- if (ie_l3_msg) {
- msg->l3h = (uint8_t*)ie_l3_msg->val;
- msgb_l3trim(msg, ie_l3_msg->len);
- ran_dec_msg = (struct ran_msg){
- .msg_type = RAN_MSG_DTAP,
- .msg_name = "BSSMAP Ciphering Mode Complete (L3 Message Contents)",
- .dtap = msg,
- };
- ran_decoded(ran_dec, &ran_dec_msg);
- }
+ rc = ran_decoded(ran_dec, &ran_dec_msg);
return rc;
}