Skip to content

Double-free due to Pdo\Pgsql::setNoticeCallback() #15986

Closed
@cmb69

Description

@cmb69

Description

The following code:

<?php
class T { public function z($m) { echo $m."\n"; } public function __call($m, $p) { echo "bah $m\n"; } }
$t = new T;
$rc = new ReflectionClass(Pdo\Pgsql::class);
$db = $rc->newInstanceWithoutConstructor();
$db->setNoticeCallback([ $t, 'disp' ]);

Resulted in this output when ASan is enabled:

Fatal error: Uncaught Error: Pdo\Pgsql object is uninitialized in C:\php-sdk\phpdev\vs17\x64\pdo.php:6
Stack trace:
#0 C:\php-sdk\phpdev\vs17\x64\pdo.php(6): Pdo\Pgsql->setNoticeCallback(Array)
#1 {main}
  thrown in C:\php-sdk\phpdev\vs17\x64\pdo.php on line 6
=================================================================
==7988==ERROR: AddressSanitizer: heap-use-after-free on address 0x125fc0265150 at pc 0x7ffd212fa14f bp 0x00d3297fdc60 sp 0x00d3297fdc68
READ of size 4 at 0x125fc0265150 thread T0
    #0 0x7ffd212fa14e in zend_gc_refcount C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_types.h:1318
    #1 0x7ffd212fa566 in zval_refcount_p C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_types.h:1367
    #2 0x7ffd2130adaa in zval_call_destructor C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_execute_API.c:217
    #3 0x7ffd2133e093 in zend_hash_reverse_apply@@16 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_hash.c:2226
    #4 0x7ffd212fd2ed in shutdown_destructors C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_execute_API.c:262
    #5 0x7ffd20f35566 in zend_call_destructors C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend.c:1325
    #6 0x7ffd215da77c in php_request_shutdown C:\php-sdk\phpdev\vs17\x64\php-src\main\main.c:1912
    #7 0x7ff781407e35 in do_cli C:\php-sdk\phpdev\vs17\x64\php-src\sapi\cli\php_cli.c:1105
    #8 0x7ff781408b8a in main C:\php-sdk\phpdev\vs17\x64\php-src\sapi\cli\php_cli.c:1309
    #9 0x7ff78142dc88 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
    #10 0x7ff78142dbd1 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #11 0x7ff78142da8d in __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
    #12 0x7ff78142dcfd in mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:16
    #13 0x7ffd815e7373  (C:\WINDOWS\System32\KERNEL32.DLL+0x180017373)
    #14 0x7ffd8299cc90  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18004cc90)

0x125fc0265150 is located 0 bytes inside of 40-byte region [0x125fc0265150,0x125fc0265178)
freed by thread T0 here:
    #0 0x7ffd3c157788 in _free_dbg D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_malloc_win.cpp:240
    #1 0x7ffd20f79267 in __zend_free C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_alloc.c:3308
    #2 0x7ffd20f78ae6 in _efree@@40 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_alloc.c:2747
    #3 0x7ffd214214ca in zend_objects_store_del@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_objects_API.c:198
    #4 0x7ffd2147bd5a in rc_dtor_func@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.c:57
    #5 0x7ffd2134df54 in i_zval_ptr_dtor C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.h:45
    #6 0x7ffd213495af in zend_array_destroy@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_hash.c:1831
    #7 0x7ffd2147bd5a in rc_dtor_func@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.c:57
    #8 0x7ffd2134df54 in i_zval_ptr_dtor C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.h:45
    #9 0x7ffd213495af in zend_array_destroy@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_hash.c:1831
    #10 0x7ffd2147bd5a in rc_dtor_func@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.c:57
    #11 0x7ffd2134df54 in i_zval_ptr_dtor C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.h:45
    #12 0x7ffd21349681 in zend_array_destroy@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_hash.c:1839
    #13 0x7ffd2147bd5a in rc_dtor_func@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.c:57
    #14 0x7ffd2134df54 in i_zval_ptr_dtor C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.h:45
    #15 0x7ffd213495af in zend_array_destroy@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_hash.c:1831
    #16 0x7ffd2147bd5a in rc_dtor_func@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.c:57
    #17 0x7ffd2141c594 in i_zval_ptr_dtor C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_variables.h:45
    #18 0x7ffd2141eb3b in zend_object_dtor_property C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_objects.c:73
    #19 0x7ffd2141db60 in zend_object_std_dtor C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_objects.c:95
    #20 0x7ffd214213ea in zend_objects_store_del@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_objects_API.c:194
    #21 0x7ffd2105edaf in zend_object_release C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_objects_API.h:77
    #22 0x7ffd21061475 in zend_exception_error C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_exceptions.c:964
    #23 0x7ffd20f37c74 in zend_execute_script C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend.c:1934
    #24 0x7ffd215dc861 in php_execute_script_ex C:\php-sdk\phpdev\vs17\x64\php-src\main\main.c:2574
    #25 0x7ffd215dbd64 in php_execute_script C:\php-sdk\phpdev\vs17\x64\php-src\main\main.c:2614
    #26 0x7ff781406f3d in do_cli C:\php-sdk\phpdev\vs17\x64\php-src\sapi\cli\php_cli.c:935
    #27 0x7ff781408b8a in main C:\php-sdk\phpdev\vs17\x64\php-src\sapi\cli\php_cli.c:1309

previously allocated by thread T0 here:
    #0 0x7ffd3c1578c8 in _malloc_dbg D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_malloc_win.cpp:263
    #1 0x7ffd20f79114 in __zend_malloc C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_alloc.c:3280
    #2 0x7ffd20f78936 in _emalloc@@40 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_alloc.c:2737
    #3 0x7ffd2141c9c6 in zend_objects_new@@8 C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_objects.c:210
    #4 0x7ffd20f71911 in _object_and_properties_init C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_API.c:1823
    #5 0x7ffd20f562cf in object_init_ex C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_API.c:1846
    #6 0x7ffd2111c25d in ZEND_NEW_SPEC_CONST_UNUSED_HANDLER C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_vm_execute.h:10895
    #7 0x7ffd2107585a in execute_ex C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_vm_execute.h:58486
    #8 0x7ffd21075769 in zend_execute C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_vm_execute.h:64138
    #9 0x7ffd20f37c31 in zend_execute_script C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend.c:1927
    #10 0x7ffd215dc861 in php_execute_script_ex C:\php-sdk\phpdev\vs17\x64\php-src\main\main.c:2574
    #11 0x7ffd215dbd64 in php_execute_script C:\php-sdk\phpdev\vs17\x64\php-src\main\main.c:2614
    #12 0x7ff781406f3d in do_cli C:\php-sdk\phpdev\vs17\x64\php-src\sapi\cli\php_cli.c:935
    #13 0x7ff781408b8a in main C:\php-sdk\phpdev\vs17\x64\php-src\sapi\cli\php_cli.c:1309
    #14 0x7ff78142dc88 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
    #15 0x7ff78142dbd1 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #16 0x7ff78142da8d in __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
    #17 0x7ff78142dcfd in mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:16
    #18 0x7ffd815e7373  (C:\WINDOWS\System32\KERNEL32.DLL+0x180017373)
    #19 0x7ffd8299cc90  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18004cc90)

SUMMARY: AddressSanitizer: heap-use-after-free C:\php-sdk\phpdev\vs17\x64\php-src\Zend\zend_types.h:1318 in zend_gc_refcount
Shadow bytes around the buggy address:
  0x04a3b81cc9d0: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fd
  0x04a3b81cc9e0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x04a3b81cc9f0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x04a3b81cca00: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x04a3b81cca10: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
=>0x04a3b81cca20: fa fa fd fd fd fd fd fd fa fa[fd]fd fd fd fd fa
  0x04a3b81cca30: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd
  0x04a3b81cca40: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fa
  0x04a3b81cca50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x04a3b81cca60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x04a3b81cca70: 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
==7988==ABORTING

But I expected this output instead:

Fatal error: Uncaught Error: Pdo\Pgsql object is uninitialized in C:\php-sdk\phpdev\vs17\x64\pdo.php:6
Stack trace:
#0 C:\php-sdk\phpdev\vs17\x64\pdo.php(6): Pdo\Pgsql->setNoticeCallback(Array)
#1 {main}

What about:

 ext/pdo_pgsql/pdo_pgsql.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c
index caa2caee54..e3e913868d 100644
--- a/ext/pdo_pgsql/pdo_pgsql.c
+++ b/ext/pdo_pgsql/pdo_pgsql.c
@@ -170,7 +170,7 @@ PHP_METHOD(Pdo_Pgsql, setNoticeCallback)
 
 cleanup:
 	if (ZEND_FCC_INITIALIZED(fcc)) {
-		zend_fcc_dtor(&fcc);
+		zend_release_fcall_info_cache(&fcc);
 	}
 	RETURN_THROWS();
 }

PHP Version

PHP 8.4

Operating System

Windows

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