CVE-2021-3405 Ebml[Unicode]String::ReadData heap overflow bug on 32bit builds --[ 1. Summary An extremely exploitable heap overflow bug exists in the implementation of EbmlString::ReadData and EbmlUnicodeString::ReadData in libebml. This bug is reachable from the current stable release of vlc. --[ 2. Discussion The issue exists in the calculation of the required buffer size to store the string. The following calculation is performed: 310 auto Buffer = new (std::nothrow) char[GetSize()+1]; ... 315 input.readFully(Buffer, GetSize()); The value returned from GetSize is guaranteed to be an unisigned 64 bug number, and due to the way in which intetgers are stored and parsed in Ebml will only use the lowest 48 bits. This guarantees that the integer cannot overflow on 64but builds. However, on 32bit builds, the value is implicitly cast to a size_t in the call to new, meaning that the truncated length can be significantly shorter than the amount of data to be copied. For example, if the length of the string element is claimed to be 0xffffffff, the resultant allocation will be 0x100000000. The cast to a 32bit size_t drops the top 1 bit, meaning an array of size zero is allocated. In the event that the string element is placed maliciously at the end of the file to be parsed, an extremely exploitable controlled heap overflow can occur. --[ 3. Resolution The fix for this bug is relatively straightforward, a check must be added to ensure that the value of GetData() + 1 is less than SIZE_MAX to ensure that it will not be truncated in the call to new. --[ 4. Proof of Concept The following proof of concept file shows the behaviour in the latest (at time of writing) version of vlc on Ubuntu 10.10. $ sudo apt install vlc:i386 gdb $ wget https://kryc.blob.core.windows.net/files/libebml-poc.mkv $ gdb -q vlc $$ r libebml-poc.mkv