You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Argument corruption when calling XMLReader::open or XMLReader::XML non-statically with observer active #11548
The $flags argument to XMLReader::XML() becomes garbage. It is a heap address.
Run under gdb to make it more obvious:
gdb --args php8.2 -d extension=tideways_xhprof xmlreader.php
...
(gdb) source .gdbinit
(gdb) break zim_XMLReader_XML
Function "zim_XMLReader_XML" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (zim_XMLReader_XML) pending.
(gdb) run
Starting program: /usr/bin/php8.2 -d extension=tideways_xhprof xmlreader.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, zim_XMLReader_XML (execute_data=0x7ffff4e13170, return_value=0x7fffffffaa48) at ./ext/xmlreader/php_xmlreader.c:1013
1013 {
(gdb) zbacktrace
[0x7ffff4e13170] XMLReader->XML("<root></root>", NULL, 140737301786784) [internal function]
[0x7ffff4e130a0] ObserverTest->__construct() /home/tstarling/src/php/php8.2-8.2.7/xmlreader.php:6
[0x7ffff4e13020] (main) /home/tstarling/src/php/php8.2-8.2.7/xmlreader.php:11
Depending on what bits are set in the heap address passed for $flags, libxml_get_last_error() may return an error.
Setting a hardware watchpoint indicates that this assignment on line 236 of zend_observer.c is overwriting the argument, which at this point is already on the VM stack:
Note that XMLReader::XML() and XMLReader::open() are special in that they can be called either statically or non-statically. The bug occurs when calling them non-statically.
Confirmed, but if a bug only reproduces when an extension is installed...
#0 zim_XMLReader_XML (execute_data=0x7ffff0208170, return_value=0x7fffffffb0c0)
at /home/ubuntu/php/php-8.2.7/src/ext/xmlreader/php_xmlreader.c:1013
#1 0x0000555556910777 in execute_internal (execute_data=0x7ffff0208170, return_value=0x7fffffffb0c0)
at /home/ubuntu/php/php-8.2.7/src/Zend/zend_execute.c:3731
#2 0x00007ffff079cb87 in tideways_xhprof_execute_internal (execute_data=0x7ffff0208170, return_value=0x7fffffffb0c0)
at /home/ubuntu/php/php-profiler-extension/tideways_xhprof.c:234
#3 0x00005555569277cf in ZEND_DO_FCALL_SPEC_OBSERVER_HANDLER () at /home/ubuntu/php/php-8.2.7/src/Zend/zend_vm_execute.h:2063
#4 0x0000555556a6a872 in execute_ex (ex=0x7ffff0208020) at /home/ubuntu/php/php-8.2.7/src/Zend/zend_vm_execute.h:56072
#5 0x0000555556a7d515 in zend_execute (op_array=0x7ffff028a140, return_value=0x0)
at /home/ubuntu/php/php-8.2.7/src/Zend/zend_vm_execute.h:60396
#6 0x00005555568820d7 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/ubuntu/php/php-8.2.7/src/Zend/zend.c:1827
#7 0x000055555670db86 in php_execute_script (primary_file=0x7fffffffcc70) at /home/ubuntu/php/php-8.2.7/src/main/main.c:2542
#8 0x0000555556c52ff6 in do_cli (argc=4, argv=0x604000000290) at /home/ubuntu/php/php-8.2.7/src/sapi/cli/php_cli.c:964
#9 0x0000555556c54d2c in main (argc=4, argv=0x604000000290) at /home/ubuntu/php/php-8.2.7/src/sapi/cli/php_cli.c:1333
Suggests the bug is in the extension.
And I can't help but notice that the extension hasn't been updated since PHP 8.0...
That's really the worst hack :-)
XMLReader::open and XMLReader::XML are copied in minit, then returned directly in xmlreader_get_method.
The functions not being properly registered causes them to be skipped over in zend_observer_post_startup, which adds the temporary for all registered functions.
Activity
damianwadley commentedon Jun 28, 2023
Confirmed, but if a bug only reproduces when an extension is installed...
Suggests the bug is in the extension.
And I can't help but notice that the extension hasn't been updated since PHP 8.0...
tstarling commentedon Jun 28, 2023
I reproduced it with the zend_test extension on the current git master:
Girgias commentedon Jun 28, 2023
Assigning @bwoebi as they know something about the observer API AFAIK
bwoebi commentedon Jun 30, 2023
That's really the worst hack :-)
XMLReader::open and XMLReader::XML are copied in minit, then returned directly in xmlreader_get_method.
The functions not being properly registered causes them to be skipped over in zend_observer_post_startup, which adds the temporary for all registered functions.
Fix GH-11548 (Argument corruption when calling XMLReader::open or XML…