Skip to content

Commit

Permalink
Fix UAF when removing doctype and using foreach iteration
Browse files Browse the repository at this point in the history
This is an old bug, but this is pretty easy to fix.
It's basically applying the same fix as I did for e878b9f.
Reported by YuanchengJiang.

Closes GH-15143.
  • Loading branch information
nielsdos committed Jul 30, 2024
1 parent 58cf903 commit b282dd7
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 2 deletions.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion ext/dom/dom_iterators.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
curnode = (xmlNodePtr) nodep->properties;
} else {
curnode = (xmlNodePtr) nodep->children;
curnode = dom_nodelist_iter_start_first_child(nodep);
}
} else {
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
Expand Down
2 changes: 1 addition & 1 deletion ext/dom/nodelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* Since:
*/

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 */
Expand Down
1 change: 1 addition & 0 deletions ext/dom/php_dom.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,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_OBJ(__ptr, __id, __prtype, __intern) { \
__intern = Z_DOMOBJ_P(__id); \
Expand Down
26 changes: 26 additions & 0 deletions ext/dom/tests/uaf_doctype_iterator.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
UAF when removing doctype and iterating over the child nodes
--EXTENSIONS--
dom
--CREDITS--
Yuancheng Jiang
--FILE--
<?php
$dom = new DOMDocument;
$dom->loadXML(<<<XML
<!DOCTYPE foo [
<!ENTITY foo1 "bar1">
]>
<foo>&foo1;</foo>
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)
}

0 comments on commit b282dd7

Please sign in to comment.