Skip to content

UAF when using document as a child #16535

Closed
@chibinz

Description

@chibinz

Description

The following code:

<?php

$v2 = new DOMDocument ( "t" );
$v4 = new DOMElement ( "Cg" , "w" , "X" );

$v2 -> loadHTML ( "t" );
$v2 -> adoptNode ( $v4 );
$v4 -> appendChild ( $v2 );
$v2 -> loadHTML ( "oU" , 0 );

Resulted in this output:

=================================================================
==1563==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f000000640 at pc 0x5613c2bcd8c8 bp 0x7fff66667760 sp 0x7fff66667758
READ of size 8 at 0x60f000000640 thread T0
    #0 0x5613c2bcd8c7 in php_libxml_set_old_ns_list /tmp/php-asan/ext/libxml/libxml.c:130:6
    #1 0x5613c2bcf53d in php_libxml_node_free /tmp/php-asan/ext/libxml/libxml.c:311:5
    #2 0x5613c2bd579b in php_libxml_node_free_resource /tmp/php-asan/ext/libxml/libxml.c:1435:5
    #3 0x5613c2bd587f in php_libxml_node_decrement_resource /tmp/php-asan/ext/libxml/libxml.c:1449:4
    #4 0x5613c2da3f7f in dom_objects_free_storage /tmp/php-asan/ext/dom/php_dom.c:1450:4
    #5 0x5613c3f5faab in zend_objects_store_del /tmp/php-asan/Zend/zend_objects_API.c:194:4
    #6 0x5613c3fc6446 in rc_dtor_func /tmp/php-asan/Zend/zend_variables.c:57:2
    #7 0x5613c3fc6534 in i_zval_ptr_dtor /tmp/php-asan/Zend/zend_variables.h:45:4
    #8 0x5613c3fc6484 in zval_ptr_dtor /tmp/php-asan/Zend/zend_variables.c:84:2
    #9 0x5613c3e5c9e9 in _zend_hash_del_el_ex /tmp/php-asan/Zend/zend_hash.c:1487:3
    #10 0x5613c3e5baba in _zend_hash_del_el /tmp/php-asan/Zend/zend_hash.c:1514:2
    #11 0x5613c3e649fa in zend_hash_reverse_apply /tmp/php-asan/Zend/zend_hash.c:2230:5
    #12 0x5613c3b80db0 in shutdown_destructors /tmp/php-asan/Zend/zend_execute_API.c:262:4
    #13 0x5613c3fdf02e in zend_call_destructors /tmp/php-asan/Zend/zend.c:1326:3
    #14 0x5613c37fdfef in php_request_shutdown /tmp/php-asan/main/main.c:1912:3
    #15 0x5613c3fee744 in do_cli /tmp/php-asan/sapi/cli/php_cli.c:1106:3
    #16 0x5613c3fea0ec in main /tmp/php-asan/sapi/cli/php_cli.c:1310:18
    #17 0x7f1972e29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #18 0x7f1972e29e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #19 0x5613c2a02de4 in _start (/workspaces/TriFuzz/targets/php-asan/bin/php+0x402de4)

0x60f000000640 is located 96 bytes inside of 176-byte region [0x60f0000005e0,0x60f000000690)
freed by thread T0 here:
    #0 0x5613c2a87702 in free /opt/llvm-15-build/llvm-15.x/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
    #1 0x5613c2bcf58e in php_libxml_node_free /tmp/php-asan/ext/libxml/libxml.c:318:4
    #2 0x5613c2bce143 in php_libxml_node_free_list /tmp/php-asan/ext/libxml/libxml.c:382:4
    #3 0x5613c2bd5709 in php_libxml_node_free_resource /tmp/php-asan/ext/libxml/libxml.c:1430:5
    #4 0x5613c2bd587f in php_libxml_node_decrement_resource /tmp/php-asan/ext/libxml/libxml.c:1449:4
    #5 0x5613c2da3f7f in dom_objects_free_storage /tmp/php-asan/ext/dom/php_dom.c:1450:4
    #6 0x5613c3f5faab in zend_objects_store_del /tmp/php-asan/Zend/zend_objects_API.c:194:4
    #7 0x5613c3fc6446 in rc_dtor_func /tmp/php-asan/Zend/zend_variables.c:57:2
    #8 0x5613c3fc6534 in i_zval_ptr_dtor /tmp/php-asan/Zend/zend_variables.h:45:4
    #9 0x5613c3fc6484 in zval_ptr_dtor /tmp/php-asan/Zend/zend_variables.c:84:2
    #10 0x5613c3e5c9e9 in _zend_hash_del_el_ex /tmp/php-asan/Zend/zend_hash.c:1487:3
    #11 0x5613c3e5baba in _zend_hash_del_el /tmp/php-asan/Zend/zend_hash.c:1514:2
    #12 0x5613c3e649fa in zend_hash_reverse_apply /tmp/php-asan/Zend/zend_hash.c:2230:5
    #13 0x5613c3b80db0 in shutdown_destructors /tmp/php-asan/Zend/zend_execute_API.c:262:4
    #14 0x5613c3fdf02e in zend_call_destructors /tmp/php-asan/Zend/zend.c:1326:3
    #15 0x5613c37fdfef in php_request_shutdown /tmp/php-asan/main/main.c:1912:3
    #16 0x5613c3fee744 in do_cli /tmp/php-asan/sapi/cli/php_cli.c:1106:3
    #17 0x5613c3fea0ec in main /tmp/php-asan/sapi/cli/php_cli.c:1310:18
    #18 0x7f1972e29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

previously allocated by thread T0 here:
    #0 0x5613c2a879ae in malloc /opt/llvm-15-build/llvm-15.x/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3
    #1 0x7f1973355b2d in htmlNewDocNoDtD (/lib/x86_64-linux-gnu/libxml2.so.2+0x91b2d) (BuildId: aebf8e42966c3ce475ff9d9d51a762831adcbb61)

SUMMARY: AddressSanitizer: heap-use-after-free /tmp/php-asan/ext/libxml/libxml.c:130:6 in php_libxml_set_old_ns_list
Shadow bytes around the buggy address:
  0x0c1e7fff8070: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x0c1e7fff8080: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c1e7fff8090: fd fd fd fd fd fd fa fa fa fa fa fa fa fa fd fd
  0x0c1e7fff80a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c1e7fff80b0: fd fd fd fd fa fa fa fa fa fa fa fa fd fd fd fd
=>0x0c1e7fff80c0: fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd
  0x0c1e7fff80d0: fd fd fa fa fa fa fa fa fa fa 00 00 00 00 00 00
  0x0c1e7fff80e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1e7fff80f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1e7fff8100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1e7fff8110: 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
==1563==ABORTING

I pulled the latest commit of master and found there are still some bugs in the DOM extension. The fundamental issue seems to be that libxml has its own way of memory management, and the abstraction on top provided by PHP (DOMNodes) is likely leaky. Should I continue reporting this kind of bugs? (Don't want to overwhelm you guys:).

PHP Version

PHP 8.5.0-dev

Operating System

No response

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