[php-src] Issue #23353: ext/dom: `DOMDocument::adoptNode()` leaves dangling wrappers under later siblings on 8.3 and 8.4

[email protected] (alexandre-daubois)
Newsgroups php.bugs
Message-ID <[email protected]>
Issue: https://github.com/php/php-src/issues/23353
Author: alexandre-daubois

### Description

The following code:

```php
<?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

```plain
8.3-8.4
```

### Operating System

_No response_
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.