From 862edf04bb0d171522c14ef8392bff0c6ab08b12 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 12 Mar 2021 15:44:13 +0100 Subject: [PATCH 1/2] Fix #66783: UAF when appending DOMDocument to element According to the DOM standard, elements may only contain element, text, processing instruction and comment nodes[1]. It is also specified that a HierarchyRequestError should be thrown if a document is to be inserted[2]. We follow that standard, and prevent the use-after-free this way. [1] [2] --- ext/dom/php_dom.c | 4 ++++ ext/dom/tests/bug66783.phpt | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 ext/dom/tests/bug66783.phpt diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 6bc72e9f97940..6d49f7dd270f7 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -1302,6 +1302,10 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) { xmlNodePtr nodep; + if (child->type == XML_DOCUMENT_NODE) { + return FAILURE; + } + if (parent == NULL || child == NULL || child->doc != parent->doc) { return SUCCESS; } diff --git a/ext/dom/tests/bug66783.phpt b/ext/dom/tests/bug66783.phpt new file mode 100644 index 0000000000000..98981a88f6e26 --- /dev/null +++ b/ext/dom/tests/bug66783.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #66783 (UAF when appending DOMDocument to element) +--SKIPIF-- + +--FILE-- +loadXML(''); +$e = $doc->createElement('e'); +try { + $e->appendChild($doc); +} catch (DOMException $ex) { + echo $ex->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +Hierarchy Request Error From 1d9537bed14c9425f73bce4095b97bb03bc7a031 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 15 Mar 2021 10:26:50 +0100 Subject: [PATCH 2/2] Fix order of code and indentation --- ext/dom/php_dom.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 6d49f7dd270f7..2f2878d5e1521 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -1302,14 +1302,14 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) { xmlNodePtr nodep; + if (parent == NULL || child == NULL || child->doc != parent->doc) { + return SUCCESS; + } + if (child->type == XML_DOCUMENT_NODE) { return FAILURE; } - if (parent == NULL || child == NULL || child->doc != parent->doc) { - return SUCCESS; - } - nodep = parent; while (nodep) {