[php-src] Issue #24707: Use-after-free in opendir() when a user wrapper unregisters itself
| From: | vi3tL0u1s | Date: | Mon, 26 Oct 2026 00:06:18 +0000 |
| Subject: | [php-src] Issue #24707: Use-after-free in opendir() when a user wrapper unregisters itself | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-253200@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/24707
Author: vi3tL0u1s
### Description
The following code:
```php
<?php
class W {
function dir_opendir() {
stream_wrapper_unregister('foo');
}
}
stream_wrapper_register('foo', 'W');
opendir('foo://');
```
Resulted in this output:
```
Deprecated: Creation of dynamic property W::$context is deprecated in /path/to/poc.php on line 8
=================================================================
==PID==ERROR: AddressSanitizer: heap-use-after-free on address 0x50400006f990 at pc 0x563df514c976
bp 0x7fff59f8daf0 sp 0x7fff59f8dae0
READ of size 8 at 0x50400006f990 thread T0
#0 0x563df514c975 in php_stream_display_wrapper_errors php-src/main/streams/stream_errors.c:835
#1 0x563df515a677 in _php_stream_opendir php-src/main/streams/streams.c:2115
#2 0x563df4e5190b in _php_do_opendir php-src/ext/standard/dir.c:122
#3 0x563df4e51e0a in zif_opendir php-src/ext/standard/dir.c:146
#4 0x563df4b9f238 in zif_phar_opendir php-src/ext/phar/func_interceptors.c:79
#5 0x563df53fa1af in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER
php-src/Zend/zend_vm_execute.h:1323
#6 0x563df5566e5c in execute_ex php-src/Zend/zend_vm_execute.h:110836
#7 0x563df557b05f in zend_execute php-src/Zend/zend_vm_execute.h:116055
#8 0x563df56f429a in zend_execute_script php-src/Zend/zend.c:1986
#9 0x563df50e2891 in php_execute_script_ex php-src/main/main.c:2636
#10 0x563df50e2dee in php_execute_script php-src/main/main.c:2676
#11 0x563df56fa06c in do_cli php-src/sapi/cli/php_cli.c:941
#12 0x563df56fc849 in do_php_cli php-src/sapi/cli/php_cli.c:1354
#13 0x563df56f5124 in main php-src/sapi/cli/php_cli_main.c:18
#14 0x7f107bd61d8f (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
#15 0x7f107bd61e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
#16 0x563df4006ef4 in _start (php-src/sapi/cli/php+0x606ef4)
0x50400006f990 is located 0 bytes inside of 40-byte region [0x50400006f990,0x50400006f9b8)
freed by thread T0 here:
#0 0x7f107c4fc537 in __interceptor_free libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x563df52b1f98 in __zend_free php-src/Zend/zend_alloc.c:4097
#2 0x563df52ab660 in _efree php-src/Zend/zend_alloc.c:3049
#3 0x563df5161e29 in stream_wrapper_dtor php-src/main/streams/userspace.c:72
#4 0x563df566109c in zend_resource_dtor php-src/Zend/zend_list.c:72
#5 0x563df5661bce in list_entry_destructor php-src/Zend/zend_list.c:179
#6 0x563df55b0608 in _zend_hash_packed_del_val php-src/Zend/zend_hash.c:1695
#7 0x563df55b2640 in zend_hash_index_del php-src/Zend/zend_hash.c:1940
#8 0x563df5660d28 in zend_list_delete php-src/Zend/zend_list.c:48
#9 0x563df5163af5 in user_wrapper_opendir php-src/main/streams/userspace.c:452
#10 0x563df515a591 in _php_stream_opendir php-src/main/streams/streams.c:2107
#11 0x563df4e5190b in _php_do_opendir php-src/ext/standard/dir.c:122
#12 0x563df4e51e0a in zif_opendir php-src/ext/standard/dir.c:146
#13 0x563df4b9f238 in zif_phar_opendir php-src/ext/phar/func_interceptors.c:79
#14 0x563df53fa1af in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER
php-src/Zend/zend_vm_execute.h:1323
#15 0x563df5566e5c in execute_ex php-src/Zend/zend_vm_execute.h:110836
#16 0x563df557b05f in zend_execute php-src/Zend/zend_vm_execute.h:116055
#17 0x563df56f429a in zend_execute_script php-src/Zend/zend.c:1986
#18 0x563df50e2891 in php_execute_script_ex php-src/main/main.c:2636
#19 0x563df50e2dee in php_execute_script php-src/main/main.c:2676
#20 0x563df56fa06c in do_cli php-src/sapi/cli/php_cli.c:941
#21 0x563df56fc849 in do_php_cli php-src/sapi/cli/php_cli.c:1354
#22 0x563df56f5124 in main php-src/sapi/cli/php_cli_main.c:18
#23 0x7f107bd61d8f (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
previously allocated by thread T0 here:
#0 0x7f107c4fc887 in __interceptor_malloc libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x563df52b1c31 in __zend_malloc php-src/Zend/zend_alloc.c:4068
#2 0x563df52ab581 in _emalloc php-src/Zend/zend_alloc.c:3039
#3 0x563df52ac4ac in _ecalloc php-src/Zend/zend_alloc.c:3127
#4 0x563df5163ea9 in zif_stream_wrapper_register php-src/main/streams/userspace.c:477
#5 0x563df53fa1af in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER
php-src/Zend/zend_vm_execute.h:1323
#6 0x563df5566e5c in execute_ex php-src/Zend/zend_vm_execute.h:110836
#7 0x563df557b05f in zend_execute php-src/Zend/zend_vm_execute.h:116055
#8 0x563df56f429a in zend_execute_script php-src/Zend/zend.c:1986
#9 0x563df50e2891 in php_execute_script_ex php-src/main/main.c:2636
#10 0x563df50e2dee in php_execute_script php-src/main/main.c:2676
#11 0x563df56fa06c in do_cli php-src/sapi/cli/php_cli.c:941
#12 0x563df56fc849 in do_php_cli php-src/sapi/cli/php_cli.c:1354
#13 0x563df56f5124 in main php-src/sapi/cli/php_cli_main.c:18
#14 0x7f107bd61d8f (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
SUMMARY: AddressSanitizer: heap-use-after-free php-src/main/streams/stream_errors.c:835 in
php_stream_display_wrapper_errors
```
To reproduce:
```
USE_ZEND_ALLOC=0 ASAN_OPTIONS=detect_leaks=0:symbolize=1 ./php-src/sapi/cli/php poc.php
```
Without
USE_ZEND_ALLOC=0 ASAN reports a SEGV in strcmp.
Commit:
```
49b2bc4532ec00859256707ac3771657d2889808
```
This bug was found by EyeQ, [Following Dragons: Code Review-Guided
Fuzzing](https://arxiv.org/pdf/2602.10487) (to appear at ICSE 2027).
### PHP Version
```plain
PHP 8.7.0-dev (cli) (built: Oct 26 2026 10:28:24) (NTS DEBUG)
Copyright © The PHP Group and Contributors
Zend Engine v4.7.0-dev, Copyright © Zend by Perforce
```
### Operating System
Ubuntu 22.04