TALOS-2026-2441
CVE-2026-11315
A out-of-bounds read vulnerability exists in the dr_mp3 drmp3_init_internal functionality of dr_libs (version(s): 0.7.3). A specially crafted .mp3 file can lead to an out-of-bounds read. An attacker can provide a malicious file to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
dr_libs (version(s): 0.7.3)
dr_libs - https://github.com/mackron/dr_libs
4.3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
CWE-125 - Out-of-bounds Read
dr_libs is a collection of high-quality, single-file audio decoding libraries for C and C++, developed by David Reid (mackron). It is popular in the game development and embedded systems communities because it is extremely easy to integrate.
dr_mp3 is the MPEG Layer III (MP3) decoder from that collection. It is a single header that drops into any project needing MP3 playback without extra build steps and is widely used in games, audio tools and media applications.
Frame sync detection is the first step when dr_mp3 processes input. The decoder scans for a valid MPEG frame header by checking the sync word and validating the layer, bitrate and sample-rate fields through drmp3_hdr_valid at [1]:
static int drmp3_hdr_valid(const drmp3_uint8 *h)
{
return h[0] == 0xff && [1]
((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) &&
(DRMP3_HDR_GET_LAYER(h) != 0) &&
(DRMP3_HDR_GET_BITRATE(h) != 15) &&
(DRMP3_HDR_GET_SAMPLE_RATE(h) != 3);
}
Once a valid frame header is found, drmp3_init_internal reads the first frame and parses the MPEG side information to locate a potential Xing or Info VBR tag. The side information tells the decoder where the audio payload begins within the frame. Parsing is driven by drmp3_L3_read_side_info, a bitstream reader that advances its own bit position bs.pos independently of the frame’s allocation size.
After side info parsing, pTagData is computed by adding the byte offset bs.pos/8 to the frame base at [2] and the 4-byte Xing/Info identifier is read through that pointer at [3]. No bounds check ensures that pTagData still points within the allocated frame buffer:
drmp3_bs_init(&bs, pFirstFrameData + DRMP3_HDR_SIZE, firstFrameInfo.frame_bytes - DRMP3_HDR_SIZE);
if (DRMP3_HDR_IS_CRC(pFirstFrameData)) {
drmp3_bs_get_bits(&bs, 16); /* CRC. */
}
if (drmp3_L3_read_side_info(&bs, grInfo, pFirstFrameData) >= 0) {
drmp3_bool32 isXing = DRMP3_FALSE;
drmp3_bool32 isInfo = DRMP3_FALSE;
const drmp3_uint8* pTagData;
const drmp3_uint8* pTagDataBeg;
pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8); [2]
pTagData = pTagDataBeg;
/* Check for both "Xing" and "Info" identifiers. */
isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && pTagData[2] == 'n' && pTagData[3] == 'g'); [3]
isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && pTagData[2] == 'f' && pTagData[3] == 'o');
With a truncated frame, side info parsing advances bs.pos to a bit position whose byte offset bs.pos/8 exceeds firstFrameInfo.frame_bytes - DRMP3_HDR_SIZE, so pTagData lands past the end of the heap-allocated frame buffer before any guard runs. The pTagData[0] access at [3] is therefore the first read off the end of the allocation and the subsequent pTagData[1..3] comparisons continue past it.
AddressSanitizer confirms a heap-buffer-overflow READ of 1 byte at drmp3_init_internal. The faulting address is 0 bytes after a 46-byte heap region (the first byte past the frame allocation), matching the pTagData[0] dereference at [3]. The crafted MP3 wraps a truncated MPEG 2.5 Layer III frame that is too short to contain both the side information and the 4-byte tag identifier:
==382003==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c3ff6fe003e at pc 0x000000506937 bp 0x7fffffffb670 sp 0x7fffffffb668
READ of size 1 at 0x7c3ff6fe003e thread T0
#0 0x000000506936 in drmp3_init_internal dr_mp3.h:3192:27
#1 0x00000050774a in drmp3_init_memory_with_metadata dr_mp3.h:3390:14
#2 0x000000513238 in drmp3_init_memory dr_mp3.h:3409:12
#3 0x000000513238 in main harness_replay.c:44:7
#4 0x7ffff7c785b4 in __libc_start_call_main (/lib64/libc.so.6+0x35b4) (BuildId: ff0267465bc3d76e21003b3bc5598fd5ee63e261)
#5 0x7ffff7c78667 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3667) (BuildId: ff0267465bc3d76e21003b3bc5598fd5ee63e261)
#6 0x000000400704 in _start (build/target.asan+0x400704) (BuildId: 5eb8a7784f372cf93e98345dc74f9115937900e5)
0x7c3ff6fe003e is located 0 bytes after 46-byte region [0x7c3ff6fe0010,0x7c3ff6fe003e)
allocated by thread T0 here:
#0 0x0000004a5bf8 in malloc (build/target.asan+0x4a5bf8) (BuildId: 5eb8a7784f372cf93e98345dc74f9115937900e5)
#1 0x0000005131dd in main harness_replay.c:35:24
#2 0x7ffff7c785b4 in __libc_start_call_main (/lib64/libc.so.6+0x35b4) (BuildId: ff0267465bc3d76e21003b3bc5598fd5ee63e261)
#3 0x7ffff7c78667 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3667) (BuildId: ff0267465bc3d76e21003b3bc5598fd5ee63e261)
#4 0x000000400704 in _start (build/target.asan+0x400704) (BuildId: 5eb8a7784f372cf93e98345dc74f9115937900e5)
SUMMARY: AddressSanitizer: heap-buffer-overflow dr_mp3.h:3192:27 in drmp3_init_internal
0x7c3ff6fdfd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7c3ff6fdfe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7c3ff6fdfe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7c3ff6fdff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7c3ff6fdff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7c3ff6fe0080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x7c3ff6fe0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x7c3ff6fe0180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x7c3ff6fe0200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x7c3ff6fe0280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
==382003==ABORTING
Vendor Link: https://github.com/mackron/dr_libs
Vendor Notes: Vendor had not replied. Please check their GitHub repository for latest release and information regarding the product.
2026-07-02 - Cisco - Vendor Notification
2026-07-16 - Cisco - Follow-up sent
2026-09-15 - Cisco - Follow-up sent
2026-11-10 - Cisco - Published
Ankur Tyagi of Cisco Talos