Skip to content

Calling the constructor again on a DOM object after it is in a document causes UAF #16777

Closed

Description

@YuanchengJiang

Description

The following code:

<?php
$text = new DOMText('my value');
$doc = new DOMDocument();
$doc->loadXML(<<<XML
<container/>
XML);
$doc->documentElement->appendChild($text);
$text->__construct("\nmy new new value");
$doc->documentElement->appendChild($text);
$fusion = $text;
$dom2 = new DOMDocument();
$dom2->loadXML('<xml><child/></xml>');
$dom2->firstChild->firstChild->appendChild($fusion);

Resulted in this output:

=================================================================
==244946==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c00001c008 at pc 0x563763d8fa67 bp 0x7ffcd1823e60 sp 0x7ffcd1823e58
READ of size 4 at 0x60c00001c008 thread T0
    #0 0x563763d8fa66 in dom_objects_free_storage /php-src/ext/dom/php_dom.c:1444:13
    #1 0x5637677f0dac in zend_objects_store_del /php-src/Zend/zend_objects_API.c:194:4
    #2 0x5637678f5289 in rc_dtor_func /php-src/Zend/zend_variables.c:57:2
    #3 0x5637678f54ee in i_zval_ptr_dtor /php-src/Zend/zend_variables.h:45:4
    #4 0x5637678f52c4 in zval_ptr_dtor /php-src/Zend/zend_variables.c:84:2
    #5 0x563767454245 in _zend_hash_del_el_ex /php-src/Zend/zend_hash.c:1487:3
    #6 0x563767451b9d in _zend_hash_del_el /php-src/Zend/zend_hash.c:1514:2
    #7 0x563767466111 in zend_hash_graceful_reverse_destroy /php-src/Zend/zend_hash.c:2039:4
    #8 0x563766bbd6c6 in zend_shutdown_executor_values /php-src/Zend/zend_execute_API.c:287:3
    #9 0x563766bc9163 in shutdown_executor /php-src/Zend/zend_execute_API.c:445:2
    #10 0x56376793afe5 in zend_deactivate /php-src/Zend/zend.c:1347:2
    #11 0x5637662463bc in php_request_shutdown /php-src/main/main.c:1950:2
    #12 0x5637679614c0 in do_cli /php-src/sapi/cli/php_cli.c:1109:3
    #13 0x563767958734 in main /php-src/sapi/cli/php_cli.c:1313:18
    #14 0x7ff44763dd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
    #15 0x7ff44763de3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
    #16 0x563763206dc4 in _start (/php-src/sapi/cli/php+0x2606dc4) (BuildId: 20af4719de442dec750a3760c5c820f580cf6aba)

0x60c00001c008 is located 8 bytes inside of 120-byte region [0x60c00001c000,0x60c00001c078)
freed by thread T0 here:
    #0 0x56376328c542 in free (/php-src/sapi/cli/php+0x268c542) (BuildId: 20af4719de442dec750a3760c5c820f580cf6aba)
    #1 0x7ff44832780b in xmlFreeNodeList (/lib/x86_64-linux-gnu/libxml2.so.2+0x6480b) (BuildId: aebf8e42966c3ce475ff9d9d51a762831adcbb61)

previously allocated by thread T0 here:
    #0 0x56376328c7ee in malloc (/php-src/sapi/cli/php+0x268c7ee) (BuildId: 20af4719de442dec750a3760c5c820f580cf6aba)
    #1 0x7ff44832587b in xmlNewText (/lib/x86_64-linux-gnu/libxml2.so.2+0x6287b) (BuildId: aebf8e42966c3ce475ff9d9d51a762831adcbb61)

SUMMARY: AddressSanitizer: heap-use-after-free /php-src/ext/dom/php_dom.c:1444:13 in dom_objects_free_storage
Shadow bytes around the buggy address:
  0x0c187fffb7b0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c187fffb7c0: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x0c187fffb7d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
  0x0c187fffb7e0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c187fffb7f0: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
=>0x0c187fffb800: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x0c187fffb810: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c187fffb820: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
  0x0c187fffb830: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x0c187fffb840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fffb850: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==244946==ABORTING

PHP Version

nightly

Operating System

ubuntu 22.04

Activity

  1. devnexen commented on Nov 13, 2024

    @devnexen
    Member

    cc @nielsdos is it a different UAF case this time ?

  2. ndossche commented on Nov 13, 2024

    @ndossche
    Member

    Yes this looks different.

  3. ndossche commented on Nov 13, 2024

    @ndossche
    Member

    Reproduces on 8.4 too.
    Reduced:

    <?php
    $text = new DOMText('my value');
    $doc = new DOMDocument();
    $doc->appendChild($text);
    $text->__construct("\nmy new new value");
    $doc->appendChild($text);
    $dom2 = new DOMDocument();
    $dom2->appendChild($text);
  4. changed the title [-]heap-use-after-free at dom/php_dom.c:1444:13 in dom_objects_free_storage[/-] [+]Calling the constructor again on a DOM object after it is in a document causes UAF[/+] on Nov 13, 2024
  5. added a commit that references this issue on Nov 15, 2024
    e746fd1
  6. added 2 commits that reference this issue on Nov 16, 2024
    18b18f0
    d3fada3
  7. added a commit that references this issue on Nov 16, 2024
    cfc8361
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions