CVE-2016-1515
A use after free/double free vulnerability can occur in libmatroska while parsing
Track
elements of the MKV container.
http://matroska.org
In a specially crafted file, Track
element is being added to ElementList of both Tracks
element and Track Entry
element which causes a double free when when Tracks
and
Track Entry
objects are beeing freed.
Technical information below:
Parsing of Track
elements creates object dependencies in a following way:
+—————+
| Tracks |
| |
++—+———-+
| |
| | +—————-+
| | | |
| +——–> Track Entry |
| | |
| +–+————-+
| |
| | +—————-+
| | | |
| +—–> Track Video |
+———————> |
+—————-+
Later in the code, each element of “Tracks” is being freed by calling their respective destructor. “Track Entry” destructor in turn frees all it’s elements thus freeing “Track Video” element which the loop in “Tracks” element tries to free again causing the crash.
The initial freeing is triggered in EbmlMaster::Read: EbmlElement * ElementLevelA; // remove all existing elements, including the mandatory ones… size_t Index; for (Index=0; Index<ElementList.size(); Index++) { if (!(*ElementList[Index]).IsLocked()) { delete ElementList[Index]; } } ElementList.clear();
This delete in turn triggers the EbmlMaster destructor:
EbmlMaster::~EbmlMaster() { assert(!IsLocked()); // you’re trying to delete a locked element !!!
size_t Index;
for (Index = 0; Index < ElementList.size(); Index++) { if (!(*ElementList[Index]).IsLocked()) { delete ElementList[Index]; } } }
Similar issue is present in relation to parsing TagTargets
element which gets added to subelemet lists of both Tag
and Tags
elements.
Similar issue is present in relation to parsing CueTrackPositions
element which gets added to subelemet lists of both CuePoints
and Segment
elements.
Richard Johnson and Aleksandar Nikolic