From 9d39ff764ed6b2f81f997b6bc0b8bc7122589ce5 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 23 Nov 2024 15:58:48 +0100 Subject: [PATCH] Fix GH-16906: Reloading document can cause UAF in iterator Closes GH-16909. --- NEWS | 2 ++ ext/dom/php_dom.c | 6 ++++++ ext/dom/php_dom.h | 1 + ext/dom/tests/gh16906.phpt | 17 +++++++++++++++++ 4 files changed, 26 insertions(+) create mode 100644 ext/dom/tests/gh16906.phpt diff --git a/NEWS b/NEWS index e6f1e5a9339..30d156a3540 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,8 @@ PHP NEWS - DOM: . Fixed bug GH-16777 (Calling the constructor again on a DOM object after it is in a document causes UAF). (nielsdos) + . Fixed bug GH-16906 (Reloading document can cause UAF in iterator). + (nielsdos) - FPM: . Fixed GH-16432 (PHP-FPM 8.2 SIGSEGV in fpm_get_status). (Jakub Zelenka) diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 5c7aacefba5..7ec107dd712 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -1018,6 +1018,10 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml mapptr->baseobj = basenode; mapptr->nodetype = ntype; mapptr->ht = ht; + if (EXPECTED(doc != NULL)) { + mapptr->dict = doc->dict; + xmlDictReference(doc->dict); + } const xmlChar* tmp; @@ -1128,6 +1132,7 @@ void dom_nnodemap_objects_free_storage(zend_object *object) /* {{{ */ if (!Z_ISUNDEF(objmap->baseobj_zv)) { zval_ptr_dtor(&objmap->baseobj_zv); } + xmlDictFree(objmap->dict); efree(objmap); intern->ptr = NULL; } @@ -1158,6 +1163,7 @@ zend_object *dom_nnodemap_objects_new(zend_class_entry *class_type) objmap->cached_length = -1; objmap->cached_obj = NULL; objmap->cached_obj_index = 0; + objmap->dict = NULL; return &intern->std; } diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index fe0c5471c6c..2bccb2d5692 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -89,6 +89,7 @@ typedef struct _dom_nnodemap_object { php_libxml_cache_tag cache_tag; dom_object *cached_obj; zend_long cached_obj_index; + xmlDictPtr dict; bool free_local : 1; bool free_ns : 1; } dom_nnodemap_object; diff --git a/ext/dom/tests/gh16906.phpt b/ext/dom/tests/gh16906.phpt new file mode 100644 index 00000000000..791ca13b390 --- /dev/null +++ b/ext/dom/tests/gh16906.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-16906 (Reloading document can cause UAF in iterator) +--EXTENSIONS-- +dom +--FILE-- +loadXML(''); +$list = $doc->getElementsByTagName('strong'); +$doc->load(__DIR__."/book.xml"); +var_dump($list); +?> +--EXPECT-- +object(DOMNodeList)#2 (1) { + ["length"]=> + int(0) +}