[php-src] Issue #23352: ext/dom: UAF reading an attribute value node retained across `DOMDocument::adoptNode()`

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

### Description

The following code:

```php
<?php

$source = new DOMDocument();
$element = $source->appendChild($source->createElement('element'));
$element->setAttribute('attribute', 'victim');
$victim = $element->getAttributeNode('attribute')->firstChild;

$destination = new DOMDocument();
$destination->appendChild($destination->adoptNode($element));
unset($destination, $source, $element);

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`. So that wrapper keeps referencing the source document while its native node has moved to the destination, and releasing the destination frees it.

Asan trace :

```
==43592==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000019cc8 at pc 0x0001011263e8 bp 0x00016ef54e70 sp 0x00016ef54e68
READ of size 4 at 0x60c000019cc8 thread T0
    #0 0x0001011263e4 in php_dom_get_content_into_zval php_dom.c:2360
    #1 0x0001010b0360 in dom_characterdata_data_read characterdata.c:58
    #2 0x0001010f8bbc in dom_read_property php_dom.c:395
    #3 0x000101bc2e20 in ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER zend_vm_execute.h:95143
    #4 0x0001019f17c8 in execute_ex zend_vm_execute.h:110551
    #5 0x0001019f1f24 in zend_execute zend_vm_execute.h:115989
    #6 0x000101da0a14 in zend_execute_script zend.c:1980
    #7 0x0001017b2d5c in php_execute_script_ex main.c:2589
    #8 0x000101da5df8 in do_cli php_cli.c:933
    #9 0x000101da3820 in do_php_cli php_cli.c:1346

0x60c000019cc8 is located 8 bytes inside of 120-byte region [0x60c000019cc0,0x60c000019d38)
freed by thread T0 here:
    #0 0x00010343d258 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 0x000100f31a14 in php_libxml_decrement_doc_ref_directly libxml.c:1395
    #6 0x000100f322cc in php_libxml_node_decrement_resource libxml.c:1471
    #7 0x00010111fe3c in dom_objects_free_storage php_dom.c:1497
    #8 0x000101d46578 in zend_objects_store_del zend_objects_API.c:193
    #9 0x000101c1d760 in ZEND_UNSET_CV_SPEC_CV_UNUSED_TAILCALL_HANDLER zend_vm_execute.h:102283
    #10 0x0001019f17c8 in execute_ex zend_vm_execute.h:110551
    #11 0x0001019f1f24 in zend_execute zend_vm_execute.h:115989
    #12 0x000101da0a14 in zend_execute_script zend.c:1980
    #13 0x0001017b2d5c in php_execute_script_ex main.c:2589

previously allocated by thread T0 here:
    #0 0x00010343d164 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 0x0001010c3fec in zim_DOMElement_setAttribute element.c:473
    #5 0x000101b99fc4 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER zend_vm_execute.h
    #6 0x0001019f17c8 in execute_ex zend_vm_execute.h:110551
    #7 0x0001019f1f24 in zend_execute zend_vm_execute.h:115989
    #8 0x000101da0a14 in zend_execute_script zend.c:1980
    #9 0x0001017b2d5c in php_execute_script_ex main.c:2589

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

### PHP Version

```plain
8.3-master
```

### 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.