Skip to content

ext/dom: DOMDocument::adoptNode() leaves dangling wrappers under later siblings on 8.3 and 8.4 #23353

Description

@alexandre-daubois

Description

The following code:

<?php
$source = new DOMDocument('1.0', 'UTF-8');
$root = $source->createElement('root');
$source->appendChild($root);

$first = $source->createElement('first');
$first->appendChild($source->createTextNode('first'));
$root->appendChild($first);

$later = $source->createElement('later');
$victim = $source->createTextNode('victim');
$later->appendChild($victim);
$root->appendChild($later);

$destination = new DOMDocument('1.0', 'UTF-8');
$destination->appendChild($destination->adoptNode($root));

unset($destination, $root, $first, $later);
gc_collect_cycles();

echo $victim->data, "\n";

Produces a UAF.

When a subtree is adopted into another document, php_dom_transfer_document_ref() updates the document reference of every live PHP wrapper in that subtree, but it visits only the xmlAttr
nodes and never the value nodes under attr->children.

It is already fixed in 8.5 and above by c77a129.

ASan trace:

==35309==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000019c08 at pc 0x000104ca23e8 bp 0x00016b3d9510 sp 0x00016b3d9508
READ of size 4 at 0x60c000019c08 thread T0
    #0 0x000104ca23e4 in php_dom_get_content_into_zval php_dom.c:2360
    #1 0x000104c2c360 in dom_characterdata_data_read characterdata.c:58
    #2 0x000104c74bbc in dom_read_property php_dom.c:395
    #3 0x00010573ee20 in ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER zend_vm_execute.h:95143
    #4 0x00010556d7c8 in execute_ex zend_vm_execute.h:110551
    #5 0x00010556df24 in zend_execute zend_vm_execute.h:115989
    #6 0x00010591ca14 in zend_execute_script zend.c:1980
    #7 0x00010532ed5c in php_execute_script_ex main.c:2589
    #8 0x000105921df8 in do_cli php_cli.c:933
    #9 0x00010591f820 in do_php_cli php_cli.c:1346
    #10 0x0001864504e0 in start+0x1b4c (dyld:arm64e+0x204e0)

0x60c000019c08 is located 8 bytes inside of 120-byte region [0x60c000019c00,0x60c000019c78)
freed by thread T0 here:
    #0 0x0001070dd258 in free+0x7c (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x41258)
    #1 0x000191105048 in xmlFreeNodeList+0x1e4 (libxml2.2.dylib:arm64e+0x11048)
    #2 0x000191105120 in xmlFreeProp+0x80 (libxml2.2.dylib:arm64e+0x11120)
    #3 0x000191104fc0 in xmlFreeNodeList+0x15c (libxml2.2.dylib:arm64e+0x10fc0)
    #4 0x000191104a50 in xmlFreeDoc+0xac (libxml2.2.dylib:arm64e+0x10a50)
    #5 0x000104aada14 in php_libxml_decrement_doc_ref_directly libxml.c:1395
    #6 0x000104aae2cc in php_libxml_node_decrement_resource libxml.c:1471
    #7 0x000104c9be3c in dom_objects_free_storage php_dom.c:1497
    #8 0x0001058c2578 in zend_objects_store_del zend_objects_API.c:193
    #9 0x000105799760 in ZEND_UNSET_CV_SPEC_CV_UNUSED_TAILCALL_HANDLER zend_vm_execute.h:102283
    #10 0x00010556d7c8 in execute_ex zend_vm_execute.h:110551
    #11 0x00010556df24 in zend_execute zend_vm_execute.h:115989
    #12 0x00010591ca14 in zend_execute_script zend.c:1980
    #13 0x00010532ed5c in php_execute_script_ex main.c:2589
    #14 0x000105921df8 in do_cli php_cli.c:933
    #15 0x00010591f820 in do_php_cli php_cli.c:1346
    #16 0x0001864504e0 in start+0x1b4c (dyld:arm64e+0x204e0)

previously allocated by thread T0 here:
    #0 0x0001070dd164 in malloc+0x78 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x41164)
    #1 0x00018662b6a4 in _malloc_type_malloc_outlined+0x40 (libsystem_malloc.dylib:arm64e+0x1e6a4)
    #2 0x000191157fb4 in xmlNewText+0x28 (libxml2.2.dylib:arm64e+0x63fb4)
    #3 0x000191102b44 in xmlNewPropInternal+0x140 (libxml2.2.dylib:arm64e+0xeb44)
    #4 0x000104c3ffec in zim_DOMElement_setAttribute element.c:473
    #5 0x000105715fc4 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER zend_vm_execute.h
    #6 0x00010556d7c8 in execute_ex zend_vm_execute.h:110551
    #7 0x00010556df24 in zend_execute zend_vm_execute.h:115989
    #8 0x00010591ca14 in zend_execute_script zend.c:1980
    #9 0x00010532ed5c in php_execute_script_ex main.c:2589
    #10 0x000105921df8 in do_cli php_cli.c:933
    #11 0x00010591f820 in do_php_cli php_cli.c:1346
    #12 0x0001864504e0 in start+0x1b4c (dyld:arm64e+0x204e0)

SUMMARY: AddressSanitizer: heap-use-after-free php_dom.c:2360 in php_dom_get_content_into_zval

PHP Version

8.3-8.4

Operating System

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions