diff --git a/NEWS b/NEWS index 95de4f325ce..3cc5da3f42a 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS . Fixed case when curl_error returns an empty string. (David Carlier) +- DOM: + . Fix UAF when removing doctype and using foreach iteration. (nielsdos) + - FFI: . Fixed bug GH-14286 (ffi enum type (when enum has no name) make memory leak). (nielsdos, dstogov) diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index 3f80ffc817c..07e3c851f27 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -305,7 +305,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i if (objmap->nodetype == XML_ATTRIBUTE_NODE) { curnode = (xmlNodePtr) basep->properties; } else { - curnode = (xmlNodePtr) basep->children; + curnode = dom_nodelist_iter_start_first_child(basep); } } else { xmlNodePtr nodep = basep; diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index 96868b05437..bb58161f16e 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -49,7 +49,7 @@ static zend_always_inline void reset_objmap_cache(dom_nnodemap_object *objmap) objmap->cached_length = -1; } -static xmlNodePtr dom_nodelist_iter_start_first_child(xmlNodePtr nodep) +xmlNodePtr dom_nodelist_iter_start_first_child(xmlNodePtr nodep) { if (nodep->type == XML_ENTITY_REF_NODE) { /* See entityreference.c */ diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index cebbe47f265..86e6b131545 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -174,6 +174,7 @@ void php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object *objmap, zend void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value); int php_dom_get_namednodemap_length(dom_object *obj); int php_dom_get_nodelist_length(dom_object *obj); +xmlNodePtr dom_nodelist_iter_start_first_child(xmlNodePtr nodep); #define DOM_GET_INTERN(__id, __intern) { \ __intern = Z_DOMOBJ_P(__id); \ diff --git a/ext/dom/tests/uaf_doctype_iterator.phpt b/ext/dom/tests/uaf_doctype_iterator.phpt new file mode 100644 index 00000000000..b166a839552 --- /dev/null +++ b/ext/dom/tests/uaf_doctype_iterator.phpt @@ -0,0 +1,26 @@ +--TEST-- +UAF when removing doctype and iterating over the child nodes +--EXTENSIONS-- +dom +--CREDITS-- +Yuancheng Jiang +--FILE-- +loadXML(<< +]> +&foo1; +XML); +$ref = $dom->documentElement->firstChild; +$nodes = $ref->childNodes; +$dom->removeChild($dom->doctype); +foreach($nodes as $str) {} +var_dump($nodes); +?> +--EXPECTF-- +object(DOMNodeList)#%d (1) { + ["length"]=> + int(0) +}