From e746fd194764d9030368229694d85ebaf8bae019 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 15 Nov 2024 21:15:36 +0100 Subject: [PATCH] Fix GH-16777: Calling the constructor again on a DOM object after it is in a document causes UAF --- ext/dom/node.c | 3 +++ ext/dom/tests/gh16777_1.phpt | 24 ++++++++++++++++++++++++ ext/dom/tests/gh16777_2.phpt | 27 +++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 ext/dom/tests/gh16777_1.phpt create mode 100644 ext/dom/tests/gh16777_2.phpt diff --git a/ext/dom/node.c b/ext/dom/node.c index cc693cd8a36cf..07c6859d73017 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -1024,6 +1024,7 @@ PHP_METHOD(DOMNode, insertBefore) } if (child->doc == NULL && parentp->doc != NULL) { + xmlSetTreeDoc(child, parentp->doc); dom_set_document_ref_pointers(child, intern->document); } @@ -1188,6 +1189,7 @@ PHP_METHOD(DOMNode, replaceChild) } if (newchild->doc == NULL && nodep->doc != NULL) { + xmlSetTreeDoc(newchild, nodep->doc); dom_set_document_ref_pointers(newchild, intern->document); } @@ -1291,6 +1293,7 @@ PHP_METHOD(DOMNode, appendChild) } if (child->doc == NULL && nodep->doc != NULL) { + xmlSetTreeDoc(child, nodep->doc); dom_set_document_ref_pointers(child, intern->document); } diff --git a/ext/dom/tests/gh16777_1.phpt b/ext/dom/tests/gh16777_1.phpt new file mode 100644 index 0000000000000..d821842ace4e9 --- /dev/null +++ b/ext/dom/tests/gh16777_1.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-16777 (Calling the constructor again on a DOM object after it is in a document causes UAF) +--EXTENSIONS-- +dom +--FILE-- +appendChild($text); +$text->__construct('my new value'); +$doc->appendChild($text); +echo $doc->saveXML(); +$dom2 = new DOMDocument(); +try { + $dom2->appendChild($text); +} catch (DOMException $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- + +my value +my new value +Wrong Document Error diff --git a/ext/dom/tests/gh16777_2.phpt b/ext/dom/tests/gh16777_2.phpt new file mode 100644 index 0000000000000..a6f3a59621b45 --- /dev/null +++ b/ext/dom/tests/gh16777_2.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-16777 (Calling the constructor again on a DOM object after it is in a document causes UAF) +--EXTENSIONS-- +dom +--FILE-- +append($child = new DOMElement('child')); +$doc = new DOMDocument(); +$doc->appendChild($el); +$el->__construct('newname'); +$doc->appendChild($el); +echo $doc->saveXML(); +$dom2 = new DOMDocument(); +try { + $dom2->appendChild($el); +} catch (DOMException $e) { + echo $e->getMessage(), "\n"; +} +var_dump($child->ownerDocument === $doc); +?> +--EXPECT-- + + + +Wrong Document Error +bool(true)