Skip to content

Commit b282dd7

Browse files
committed
Fix UAF when removing doctype and using foreach iteration
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.
1 parent 58cf903 commit b282dd7

File tree

5 files changed

+32
-2
lines changed

5 files changed

+32
-2
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ PHP NEWS
1616
. Fixed case when curl_error returns an empty string.
1717
(David Carlier)
1818

19+
- DOM:
20+
. Fix UAF when removing doctype and using foreach iteration. (nielsdos)
21+
1922
- FFI:
2023
. Fixed bug GH-14286 (ffi enum type (when enum has no name) make memory
2124
leak). (nielsdos, dstogov)

ext/dom/dom_iterators.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
295295
if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
296296
curnode = (xmlNodePtr) nodep->properties;
297297
} else {
298-
curnode = (xmlNodePtr) nodep->children;
298+
curnode = dom_nodelist_iter_start_first_child(nodep);
299299
}
300300
} else {
301301
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {

ext/dom/nodelist.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* Since:
3232
*/
3333

34-
static xmlNodePtr dom_nodelist_iter_start_first_child(xmlNodePtr nodep)
34+
xmlNodePtr dom_nodelist_iter_start_first_child(xmlNodePtr nodep)
3535
{
3636
if (nodep->type == XML_ENTITY_REF_NODE) {
3737
/* See entityreference.c */

ext/dom/php_dom.h

+1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ void php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object *objmap, zend
156156
void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value);
157157
int php_dom_get_namednodemap_length(dom_object *obj);
158158
int php_dom_get_nodelist_length(dom_object *obj);
159+
xmlNodePtr dom_nodelist_iter_start_first_child(xmlNodePtr nodep);
159160

160161
#define DOM_GET_OBJ(__ptr, __id, __prtype, __intern) { \
161162
__intern = Z_DOMOBJ_P(__id); \
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
UAF when removing doctype and iterating over the child nodes
3+
--EXTENSIONS--
4+
dom
5+
--CREDITS--
6+
Yuancheng Jiang
7+
--FILE--
8+
<?php
9+
$dom = new DOMDocument;
10+
$dom->loadXML(<<<XML
11+
<!DOCTYPE foo [
12+
<!ENTITY foo1 "bar1">
13+
]>
14+
<foo>&foo1;</foo>
15+
XML);
16+
$ref = $dom->documentElement->firstChild;
17+
$nodes = $ref->childNodes;
18+
$dom->removeChild($dom->doctype);
19+
foreach($nodes as $str) {}
20+
var_dump($nodes);
21+
?>
22+
--EXPECTF--
23+
object(DOMNodeList)#%d (1) {
24+
["length"]=>
25+
int(0)
26+
}

0 commit comments

Comments
 (0)