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