Skip to content

UAF when using document as a child #16535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chibinz opened this issue Oct 21, 2024 · 2 comments
Closed

UAF when using document as a child #16535

chibinz opened this issue Oct 21, 2024 · 2 comments

Comments

@chibinz
Copy link

chibinz commented Oct 21, 2024

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

@cmb69
Copy link
Member

cmb69 commented Oct 21, 2024

Should I continue reporting this kind of bugs?

Please give us some time to figure out how to fix the existing issues (#16533, #16534, and this one).

@nielsdos nielsdos changed the title Use after free in DOM -> loadHTML UAF when using document as a child Oct 21, 2024
nielsdos added a commit to nielsdos/php-src that referenced this issue Oct 21, 2024
Documents can never be children of any node.
@nielsdos nielsdos linked a pull request Oct 21, 2024 that will close this issue
@nielsdos
Copy link
Member

Another old bug, there's probably a bunch more of these hierarchy bugs; and I bet they're old enough to legally drink.

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.

The DOMNode classes are the old-style DOM classes which have some... issues. PHP 8.4 introduces new classes in the Dom namespace (e.g. Dom\Node) which are designed to use HTML5 and follow the WHATWG DOM spec by the letter. They should be more stable (famous last words).

Should I continue reporting this kind of bugs?

Yes please. I suppose you're a researcher working on a PhD? I get that you don't want to overwhelm us, as a fellow PhD researcher I have the same concern when I report bugs to projects. Don't worry too much about it here, I can triage and likely fix these issues relatively quickly, and I'd be happy to (indirectly) help another fellow researcher.

nielsdos added a commit that referenced this issue Oct 21, 2024
* PHP-8.2:
  Fix GH-16535: UAF when using document as a child
  Fix GH-16533: Segfault when adding attribute to parent that is not an element
nielsdos added a commit that referenced this issue Oct 21, 2024
* PHP-8.3:
  Fix GH-16535: UAF when using document as a child
  Fix GH-16533: Segfault when adding attribute to parent that is not an element
nielsdos added a commit that referenced this issue Oct 21, 2024
* PHP-8.4:
  Fix GH-16535: UAF when using document as a child
  Fix GH-16533: Segfault when adding attribute to parent that is not an element
nielsdos added a commit that referenced this issue Mar 10, 2025
nielsdos added a commit that referenced this issue Mar 10, 2025
* PHP-8.2:
  Fix test GH-16535 for libxml2 2.14
  Fix tests for libxml2 2.14
nielsdos added a commit that referenced this issue Mar 10, 2025
* PHP-8.3:
  Fix test GH-16535 for libxml2 2.14
  Fix tests for libxml2 2.14
nielsdos added a commit that referenced this issue Mar 10, 2025
* PHP-8.4:
  Fix test GH-16535 for libxml2 2.14
  Fix tests for libxml2 2.14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants