Researcher: Nikita Sveshnikov (Positive Technologies)
In DOMNode::C14N(), improper removal of a xmlns libxml2 attribute from a doubly linked list can lead to a corrupt, circular linked list. The linked list is iterated in many places in PHP and libxml2, leading to DoS through segfaults, or temporal and spatial resource starvation.
$doc = Dom\HTMLDocument::createFromString(' ');
$doc->C14N();
// Segfault on cleanup
// Or
$doc = Dom\HTMLDocument::createFromString(' ');
$doc->C14N();
$svg = $doc->documentElement->childNodes[1]->childNodes[0];
foreach ($svg->attributes as $prop) {} // This will loop forever
The attribute is removed incorrectly here:
Notice the attr->prev = attr->next; instead of attr->prev->next = attr->next;. The attribute is later (correctly) restored here:
After both procedures, the following graph:
flowchart TD
A -- "Next" --> xmlns
xmlns -- "Prev" --> A
xmlns -- "Next" --> B
B -- "Prev" --> xmlns
Would result in this graph:
flowchart TD
A -- "Next" --> xmlns
xmlns -- "Prev" --> B
xmlns -- "Next" --> B
B -- "Prev" --> xmlns
B -- "Next" --> xmlns
Continuously following next will result in an infinite loop.