An attacker sending a malformed SIP message over VoLTE to a device with a Mediatek baseband can trigger the vulnerability described here.

The impact is intra-structure overflow in the baseband, triggered by malformed SDP data in VoLTE message such as SIP INVITE or MESSAGE request.

The vulnerability described in this advisory affected a wide range of Mediatek devices. The January 2024 issue of the Mediatek Security Bulletin contains this vulnerability as CVE-2023-32889.

Vulnerability Details

When a SIP message contains SDP data, first the cc_call_unpack_sdpmsg routine is invoked to unpack the message bytes into an internal representation (sdp_message_struct). Based on that, later, the session object’s des_audio structure is populated with the AMR/AMR-WB codec info. The codec info is derived from the SDP media description’s fmtp attribute’s mode-set parameter. A well formed SDP example message is provided below for clarity.

m=audio 49170 RTP/AVP 99
a=rtpmap:99 AMR-WB/16000/1
a=fmtp:99 mode-change-capability=1; octet-align=1; mode-set=0,3,5,6

Later during the SDP message handling the cc_call_sdp_get_info function further process this mode-set parameter. This vulnerable function iterates over the mode-set parameter string and extracts each parameter into an integer array within the media_config field of the volte_bw_ind_struct.

int cc_call_sdp_get_info(
	call_session_call_object_t *callobj,
	sdp_message_struct *sdp_msg,
	volte_bw_ind_struct *bw_ind
) {
	[...]
	pcVar4 = strchr(amr_cap->mode_set,',');
	if (pcVar4 == NULL) {
	  lVar9 = strtol(amr_cap->mode_set,NULL,10);
	  idx = 1;
	  (bw_ind->media_config).mode_set[0] = (kal_int8)lVar9;
	} else {
	  idx = 1;
	  lVar9 = strtol(pcVar4 + -1,NULL,10);
	  (bw_ind->media_config).mode_set[0] = (kal_int8)lVar9;
	  // [0] Loop that iterates over the comma separated string
	  do {
	    // [1] Decimal is converted to int without error checking
	    lVar9 = strtol(pcVar4 + 1,NULL,10);
	    // [2] The value is written into the mode_set array without bounds check
	    (bw_ind->media_config).mode_set[idx] = (kal_int8)lVar9;
	    idx = idx + 1;
	    pcVar4 = strchr(pcVar4 + 1,',');
	  } while (pcVar4 != NULL);
	}
	[...]

The vulnerable function iterates over the mode-set parameter string at [0]. It contains a list of integers separated by commas. Each decimal string is converted to an integer [1] without error checking. The retrieved integer value is saved in the mode_set array of the volte_event_media_config_struct structure which is a subfield of the volte_bw_ind_struct structure (see the relevant part of the structure layout below). The loop does not contain any bound check enforcement, however the input parameter string is limited in length. It is contained within a 32 element char array and if the decimals and commas alternate the destination buffer cannot be overflown.

The vulnerability is the result of the combination of lack of bound checking and the lack of error handling after the integer conversion at [1]. For each comma present in the mode-set parameter the array index is advanced, regardless whether a valid number was encountered and the conversion succeeded or not. A mode-set parameter that contains only commas and a number in the end can overflow the destination array by up to 15 bytes. This would enable the corruption of subsequent fields in the volte_event_media_config_struct structure:

+0xa4  kal_int8[16]  mode_set
+0xb4  kal_uint8     is_octet_align
+0xb5  kal_uint8     mode_change_period
+0xb6  kal_uint8     mode_change_cap
+0xb7  kal_uint8     mode_change_neighbor
+0xb8  kal_uint8     crc
+0xb9  kal_uint8     robust
+0xba  kal_uint8     interleaving
+0xbb  kal_uint8     channel
+0xbc  kal_uint16    max_red
+0xbe  kal_uint16    rtcp_rsize
+0xc0  kal_uint32    rtcpfb_type
+0xc4  kal_uint32    network_id

The cc_call_sdp_compare_info function contains a similar out of bound iteration when populating the mode_set array of a VoLTE_Event_Media_update_t structure.

Example Payload

Replace the mode-set parameter (of the SDP media description’s fmtp attribute) in a legitimate SIP INVITE as below:

payload = b";mode-set=,,,,,,,,,,,,,,,,1,2,3,4,5,6"
pattern = b"(?<=mode-change-capability=2;max-red=0)(?=\r)"
body = re.sub(pattern, payload, body)

Affected Devices

MT2735, MT6813, MT6833, MT6833P, MT6835, MT6853, MT6853T, MT6855, MT6873, MT6875, MT6877, MT6877T, MT6878, MT6879, MT6880, MT6883, MT6885, MT6886, MT6889, MT6890, MT6891, MT6893, MT6895, MT6895T, MT6896, MT6897, MT6980, MT6980D, MT6983T, MT6983W, MT6983Z, MT6985, MT6985T, MT6989, MT6990

Timeline

  • 2023.07.28. Bug reported to Mediatek PSIRT
  • 2023.08.07. Mediatek confirms vulnerability
  • 2023.11.06. Mediatek confirms CVE
  • 2024.01.02. Mediatek releases security bulletin
  • 2025.06.26. Vulnerability publicly disclosed at Troopers ‘25
  • 2025.10.01. Advisory release