CVE-2026-25713
A heap-based buffer overflow vulnerability exists in the ID3v2 parsing functionality of MediaInfoLib (version(s): 26.01). A specially crafted media file that contains ID3v2 tags can lead to arbitrary code execution. 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.
MediaInfoLib (version(s): 26.01)
MediaInfoLib - https://github.com/MediaArea/MediaInfoLib
7.8 - CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-122 - Heap-based Buffer Overflow
MediaInfo(Lib) is a convenient unified display of technical information and metadata for video and audio files.
ID3 tags are metadata containers that provide information for many types of media, mainly for audio files, like the title, artist name, year of release etc.
For compatibility with older audio players, the ID3v2 specification provides an “Unsynchronization scheme”. Due to the similarity of ID3v2 tags with actual audio data that could confuse older parsers, a NULL byte is appended to an ID3v2 tag byte. Then during decoding, if the “Unsynchronization” flag is set, the parser must correctly remove these NULL bytes from the ID3v2 data.
In File_Id3v2.cpp:516 we see the following code searching for the 0xFF00 pattern and saving the indices of the pattern to the Unsynch_List vector at (1) below. Here Buffer_Beg is the start of the ID3 data.
for (; Buffer_Cur<Buffer_End; Buffer_Cur++)
{
if (*Buffer_Cur==0xFF) // check 0xFF00
{
auto Buffer_Cur2=Buffer_Cur+1;
if (!*Buffer_Cur2)
{
Unsynch_List.push_back(Buffer_Cur2-Buffer_Beg); (1)
...
}
}
}
Then, the code reads the DataLength from the input encoded as a Big-Endian 4 byte integer at (2) and adds 4 at (3), saving the total size of the buffer at Element_Size at (4). Finally, the code allocates the Buffer_Unsynch buffer with a size of Element_Size at (5).
int32u DataLength;
if (DataLengthIndicator)
{
Get_B4 (DataLength, "Data length"); (2)
DataLength=((DataLength>>0)&0x7F)
| ((DataLength>>1)&0x3F80)
| ((DataLength>>2)&0x1FC000)
| ((DataLength>>3)&0x0FE00000);
Param_Info2(DataLength, " bytes");
}
...
if (DataLength!=(int32u)-1)
{
int64u TotalLength=4+(int64u)DataLength; (3)
...
Element_Size=TotalLength; (4)
}
...
Buffer_Unsynch=new int8u[(size_t)Element_Size]; (5)
For each previously found unsynchronization pattern index, the library copies the data from the original buffer to Unsynch_Buffer.
for (size_t Pos=0; Pos<=Unsynch_List.size(); Pos++) {
if (Pos == Unsynch_List.size())
Pos0 = (size_t)(Element_Size+Unsynch_List.size())
else
Pos0 = (Unsynch_List[Pos]);
if (Pos==0)
Pos1 = 0
else
Pos1 = (Unsynch_List[Pos-1]+1);
size_t Buffer_Unsynch_Begin = Pos1-Pos;
size_t Save_Buffer_Begin = Pos1;
size_t Size = Pos0-Pos1; (6)
std::memcpy(Buffer_Unsynch+Buffer_Unsynch_Begin, (7)
Save_Buffer+Save_Buffer_Offset+Save_Buffer_Begin,
Size);
}
At (6) the size of the data to copy is calculated by subtracting two consecutive indices and at (7) a memcpy() is performed that copies data from the input file to Buffer_Unsynch.
Note however, that there is no check regarding the size of the allocated buffer Buffer_Unsynch at (5) and the calculated Size at (6). Element_Size at (5) is an integer taken directly from the input file and the Size is calculated from the relevant indices of the 0xFF00 bytes of the ID3v2 input data.
As a result, an attacker providing a malicious file can control the size of the allocation at (5) and the size of the memcpy() at (7). Finally, an attacker fully controls the data being copied, which can result in a heap-buffer-overflow and overwrite crucial pointers in memory that can lead to remote code execution.
ASAN report:
==413353==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50b0000296b5 at pc 0x555555907342 bp 0x7fffffffd150 sp 0x7fffffffc910
WRITE of size 25806 at 0x50b0000296b5 thread T0
#0 0x555555907341 in __asan_memcpy (/fuzz/harness/build/harness_v26.01_vanilla_asan+0x3b3341) (BuildId: f8e032055fc3a50a3224b9659863548a0da63932)
#1 0x5555564b7f05 in MediaInfoLib::File_Id3v2::Data_Parse() /fuzz/src/Source/MediaInfo/Tag/File_Id3v2.cpp:603:17
#2 0x5555566f0e45 in MediaInfoLib::File__Analyze::Data_Manage() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:2852:9
#3 0x5555566ebfc3 in MediaInfoLib::File__Analyze::Buffer_Parse() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1962:10
#4 0x5555566e65c6 in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1528:14
#5 0x5555566e3df4 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1115:16
#6 0x5555566eabf8 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(MediaInfoLib::File__Analyze*, unsigned char const*, unsigned long, bool, double) /fuzz/src/ +++Source
/MediaInfo/File__Analyze.cpp:1469:10
#7 0x555556483634 in MediaInfoLib::File__Tags_Helper::Synched_Test() /fuzz/src/Source/MediaInfo/Tag/File__Tags.cpp:371:19
#8 0x555555feb145 in MediaInfoLib::File__Tags_Helper::FileHeader_Begin() /fuzz/src/Project/CMake/../../Source/MediaInfo/Tag/File__Tags.h:73:37
#9 0x555555feb145 in MediaInfoLib::File_Flv::FileHeader_Begin() /fuzz/src/Source/MediaInfo/Multiple/File_Flv.cpp:654:29
#10 0x5555566eb3eb in MediaInfoLib::File__Analyze::FileHeader_Manage() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:2568:33
#11 0x5555566e622d in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1493:14
#12 0x5555566e3df4 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1115:16
#13 0x55555680ec59 in MediaInfoLib::File__MultipleParsing::Read_Buffer_Continue() /fuzz/src/Source/MediaInfo/File__MultipleParsing.cpp:931:22
#14 0x5555566e638e in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1503:5
#15 0x5555566e3df4 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1115:16
#16 0x5555559e0423 in MediaInfoLib::MediaInfo_Internal::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/MediaInfo_Internal.cpp:+++1723
:11
#17 0x5555559e12d9 in MediaInfoLib::MediaInfo_Internal::Open(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned long long) /fuzz/ +++src/Sou
rce/MediaInfo/MediaInfo_Internal.cpp:1511:5
#18 0x55555594d8f1 in LLVMFuzzerTestOneInput /fuzz/harness/harness.cpp:6:15
#19 0x55555594d7e9 in ExecuteFilesOnyByOne /AFLplusplus/utils/aflpp_driver/aflpp_driver.c:267:7
#20 0x55555594d5d9 in LLVMFuzzerRunDriver /AFLplusplus/utils/aflpp_driver/aflpp_driver.c
#21 0x55555594d17b in main /AFLplusplus/utils/aflpp_driver/aflpp_driver.c:323:10
#22 0x7ffff7a091c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#23 0x7ffff7a0928a in __libc_start_main csu/../csu/libc-start.c:360:3
#24 0x555555869744 in _start (/fuzz/harness/build/harness_v26.01_vanilla_asan+0x315744) (BuildId: f8e032055fc3a50a3224b9659863548a0da63932)
0x50b0000296b5 is located 0 bytes after 101-byte region [0x50b000029650,0x50b0000296b5)
allocated by thread T0 here:
#0 0x55555594ad11 in operator new[](unsigned long) (/fuzz/harness/build/harness_v26.01_vanilla_asan+0x3f6d11) (BuildId: f8e032055fc3a50a3224b9659863548a0da63932)
#1 0x5555564b7e33 in MediaInfoLib::File_Id3v2::Data_Parse() /fuzz/src/Source/MediaInfo/Tag/File_Id3v2.cpp:595:28
#2 0x5555566f0e45 in MediaInfoLib::File__Analyze::Data_Manage() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:2852:9
#3 0x5555566ebfc3 in MediaInfoLib::File__Analyze::Buffer_Parse() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1962:10
#4 0x5555566e65c6 in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1528:14
#5 0x5555566e3df4 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1115:16
#6 0x5555566eabf8 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(MediaInfoLib::File__Analyze*, unsigned char const*, unsigned long, bool, double) /fuzz/src/ +++Source
/MediaInfo/File__Analyze.cpp:1469:10
#7 0x555556483634 in MediaInfoLib::File__Tags_Helper::Synched_Test() /fuzz/src/Source/MediaInfo/Tag/File__Tags.cpp:371:19
#8 0x555555feb145 in MediaInfoLib::File__Tags_Helper::FileHeader_Begin() /fuzz/src/Project/CMake/../../Source/MediaInfo/Tag/File__Tags.h:73:37
#9 0x555555feb145 in MediaInfoLib::File_Flv::FileHeader_Begin() /fuzz/src/Source/MediaInfo/Multiple/File_Flv.cpp:654:29
#10 0x5555566eb3eb in MediaInfoLib::File__Analyze::FileHeader_Manage() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:2568:33
#11 0x5555566e622d in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1493:14
#12 0x5555566e3df4 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1115:16
#13 0x55555680ec59 in MediaInfoLib::File__MultipleParsing::Read_Buffer_Continue() /fuzz/src/Source/MediaInfo/File__MultipleParsing.cpp:931:22
#14 0x5555566e638e in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1503:5
#15 0x5555566e3df4 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/File__Analyze.cpp:1115:16
#16 0x5555559e0423 in MediaInfoLib::MediaInfo_Internal::Open_Buffer_Continue(unsigned char const*, unsigned long) /fuzz/src/Source/MediaInfo/MediaInfo_Internal.cpp:+++1723
:11
#17 0x5555559e12d9 in MediaInfoLib::MediaInfo_Internal::Open(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned long long) /fuzz/ +++src/Sou
rce/MediaInfo/MediaInfo_Internal.cpp:1511:5
#18 0x55555594d8f1 in LLVMFuzzerTestOneInput /fuzz/harness/harness.cpp:6:15
#19 0x55555594d7e9 in ExecuteFilesOnyByOne /AFLplusplus/utils/aflpp_driver/aflpp_driver.c:267:7
GDB crash:
Thread 1 "harness_v26.01_" received signal SIGSEGV, Segmentation fault.
__memcpy_evex_unaligned_erms ()
at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:265
warning: 265 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory
(gdb) i r $rdi $rsi $rdx
rdi 0x4141414141414141 4702111234474983745
rsi 0x41416bebe030f40f 4702158146774299663
2026-03-25 - Initial Vendor Contact
2026-03-25 - Vendor Disclosure
2026-05-12 - Vendor Patch Release
2026-05-26 - Public Release
Dimitrios Tatsis of Cisco TALOS