Skip to content

Another UAF in DOM -> cloneNode #16595

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 25, 2024 · 1 comment
Closed

Another UAF in DOM -> cloneNode #16595

chibinz opened this issue Oct 25, 2024 · 1 comment

Comments

@chibinz
Copy link

chibinz commented Oct 25, 2024

Description

The following code:

<?php
$v0 = new DOMElement ( "jg" );
$v1 = new DOMDocument ( "Zb" );
$v2 = new DOMElement ( "IU" );
$v7 = new DOMElement ( "L" , null , "df" );
$v9 = new DOMDocument (  );

try { $v1 -> insertBefore ( $v0 , $v9 ); } catch (\Throwable) { }
$v0 -> replaceChildren ( $v7 );
$v7 -> before ( $v2 );
$v1 -> insertBefore ( $v0 );
$v2 -> cloneNode (  );

Resulted in this output:

==956555==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000008bc8 at pc 0x5600b97a4d2c bp 0x7ffe6424ba00 sp 0x7ffe6424b9f8
READ of size 4 at 0x60c000008bc8 thread T0
    #0 0x5600b97a4d2b in dom_objects_free_storage /tmp/php-asan/ext/dom/php_dom.c:1449:13
    #1 0x5600ba960c1b in zend_objects_store_del /tmp/php-asan/Zend/zend_objects_API.c:194:4
    #2 0x5600ba9c75b6 in rc_dtor_func /tmp/php-asan/Zend/zend_variables.c:57:2
    #3 0x5600ba9c76a4 in i_zval_ptr_dtor /tmp/php-asan/Zend/zend_variables.h:45:4
    #4 0x5600ba9c75f4 in zval_ptr_dtor /tmp/php-asan/Zend/zend_variables.c:84:2
    #5 0x5600ba85d919 in _zend_hash_del_el_ex /tmp/php-asan/Zend/zend_hash.c:1487:3
    #6 0x5600ba85c9ea in _zend_hash_del_el /tmp/php-asan/Zend/zend_hash.c:1514:2
    #7 0x5600ba86592a in zend_hash_reverse_apply /tmp/php-asan/Zend/zend_hash.c:2230:5
    #8 0x5600ba581ce0 in shutdown_destructors /tmp/php-asan/Zend/zend_execute_API.c:262:4
    #9 0x5600ba9e026e in zend_call_destructors /tmp/php-asan/Zend/zend.c:1330:3
    #10 0x5600ba1fee5f in php_request_shutdown /tmp/php-asan/main/main.c:1912:3
    #11 0x5600ba9ef984 in do_cli /tmp/php-asan/sapi/cli/php_cli.c:1106:3
    #12 0x5600ba9eb32c in main /tmp/php-asan/sapi/cli/php_cli.c:1310:18
    #13 0x7ff24be29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #14 0x7ff24be29e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #15 0x5600b9402de4 in _start (/workspaces/TriFuzz/targets/php-asan/bin/php+0x402de4)

0x60c000008bc8 is located 8 bytes inside of 120-byte region [0x60c000008bc0,0x60c000008c38)
freed by thread T0 here:
    #0 0x5600b9487702 in free /opt/llvm-15-build/llvm-15.x/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
    #1 0x7ff24c2c280b in xmlFreeNodeList (/lib/x86_64-linux-gnu/libxml2.so.2+0x6480b) (BuildId: aebf8e42966c3ce475ff9d9d51a762831adcbb61)

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

SUMMARY: AddressSanitizer: heap-use-after-free /tmp/php-asan/ext/dom/php_dom.c:1449:13 in dom_objects_free_storage
Shadow bytes around the buggy address:
  0x0c187fff9120: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x0c187fff9130: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c187fff9140: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c187fff9150: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
  0x0c187fff9160: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
=>0x0c187fff9170: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
  0x0c187fff9180: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
  0x0c187fff9190: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x0c187fff91a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff91b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff91c0: 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
==956555==ABORTING

Sorry for the spam, hopefully last batch of bugs in DOMNode:)

PHP Version

PHP 8.5.0-dev

Operating System

No response

@nielsdos
Copy link
Member

Ancient bug as well :(
Looks like it first changes some data of the node and only then checks for some pre-conditions in this case; breaking constraints...

nielsdos added a commit to nielsdos/php-src that referenced this issue Oct 25, 2024
We need to perform all sanity checks before doing any modification.
I don't have a reliable and easy test for this on 8.2, but I have one
for 8.4.
@nielsdos nielsdos linked a pull request Oct 25, 2024 that will close this issue
nielsdos added a commit that referenced this issue Oct 28, 2024
* PHP-8.2:
  Fix GH-16595: Another UAF in DOM -> cloneNode
  Fix GH-16593: Assertion failure in DOM->replaceChild
nielsdos added a commit that referenced this issue Oct 28, 2024
* PHP-8.3:
  Fix GH-16595: Another UAF in DOM -> cloneNode
  Fix GH-16593: Assertion failure in DOM->replaceChild
nielsdos added a commit that referenced this issue Oct 28, 2024
* PHP-8.4:
  Fix GH-16595: Another UAF in DOM -> cloneNode
  Fix GH-16593: Assertion failure in DOM->replaceChild
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.

3 participants