Skip to content

Commit 27d2555

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: ext/dom: Fix UAF in custom XPath function
2 parents 1603252 + 33a49bb commit 27d2555

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

ext/dom/tests/gh22077.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-22077 (UAF in custom XPath function)
3+
--FILE--
4+
<?php
5+
$document = new DOMDocument;
6+
$xpath = new DOMXPath($document);
7+
$xpath->registerNamespace("my", "my.ns");
8+
$xpath->registerPHPFunctionNS('my.ns', 'include', function(): DOMElement {
9+
$includedDocument = new DOMDocument;
10+
$includedDocument->loadXML('<root><uaf/><node/><uaf/></root>');
11+
return $includedDocument->documentElement;
12+
});
13+
$nodeset = $xpath->query('my:include()/uaf');
14+
$node = $nodeset->item(0);
15+
var_dump($nodeset->length);
16+
var_dump($node->ownerDocument->saveXML($node));
17+
?>
18+
--EXPECT--
19+
int(2)
20+
string(6) "<uaf/>"

ext/dom/xpath.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@
3333

3434
#ifdef LIBXML_XPATH_ENABLED
3535

36+
static dom_object *dom_xpath_intern_for_doc(dom_xpath_object *xpath_obj, xmlDocPtr doc)
37+
{
38+
if (xpath_obj->dom.document && xpath_obj->dom.document->ptr == doc) {
39+
return &xpath_obj->dom;
40+
}
41+
HashTable *node_list = xpath_obj->xpath_callbacks.node_list;
42+
if (node_list) {
43+
zval *entry;
44+
ZEND_HASH_PACKED_FOREACH_VAL(node_list, entry) {
45+
dom_object *obj = Z_DOMOBJ_P(entry);
46+
if (obj->document && obj->document->ptr == doc) {
47+
return obj;
48+
}
49+
} ZEND_HASH_FOREACH_END();
50+
}
51+
return &xpath_obj->dom;
52+
}
53+
3654
void dom_xpath_objects_free_storage(zend_object *object)
3755
{
3856
dom_xpath_object *intern = php_xpath_obj_from_obj(object);
@@ -352,7 +370,8 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern)
352370

353371
node = php_dom_create_fake_namespace_decl(nsparent, original, &child, parent_intern);
354372
} else {
355-
php_dom_create_object(node, &child, &intern->dom);
373+
dom_object *parent = dom_xpath_intern_for_doc(intern, node->doc);
374+
php_dom_create_object(node, &child, parent);
356375
}
357376
add_next_index_zval(&retval, &child);
358377
}

0 commit comments

Comments
 (0)