Bug #79820 [Com]: double-free causing heap corruption

From: Date: Mon, 13 Jul 2020 23:54:05 +0000
Subject: Bug #79820 [Com]: double-free causing heap corruption
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-228016@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=79820&edit=1 ID: 79820 Comment by: christopher dot broadbent at zencontrol dot com Reported by: christopher dot broadbent at zencontrol dot com Summary: double-free causing heap corruption Status: Open Type: Bug Package: Reproducible crash Operating System: linux debian buster PHP Version: 7.4.7 Block user comment: N Private report: N New Comment: Upgraded to 7.4.8, still crashes. > I can't find any version of PHP 7.4 that has a zend_string_release call in > php_reflection.c:225 This might be the inline of the release call being assigned weird line numbers as it runs? The frame #4 reflection_free_objects_storage (object=0x7ff047a6cb18) at ./ext/reflection/php_reflection.c:230 is calling: zend_string_release(ZEND_TYPE_NAME(type_ref->type)); Regardless, I've asked the package maintainer if there are any patches applied before he builds: https://github.com/oerdnj/deb.sury.org/issues/1433 I doubt that is the problem though as we're also hitting this issue on the official docker containers, and they don't seem to do any patching. Docker images: https://hub.docker.com/layers/php/library/php/7.4.8-buster/images/sha256-96e4c07b30977303a1bc53a269ea5284b3d85d4d89787948c3a594dc89a03698?context=explore Docker image source: https://github.com/docker-library/php/tree/master/7.4/buster Previous Comments: ------------------------------------------------------------------------ [2020-07-09 08:47:51] nikic@php.net Not seeing what could cause this. Property types getting resolved while being held by reflection is something we specifically protect against. ------------------------------------------------------------------------ [2020-07-09 08:41:17] nikic@php.net On which version/commit of PHP were the gdb backtraces gathered? I can't find any version of PHP 7.4 that has a zend_string_release call in php_reflection.c:225. The valgrind trace looks more plausible. There might be some relation to https://github.com/php/php-src/commit/c9abfaec6bf61bcef6d9651827b49cc7789018fd. ------------------------------------------------------------------------ [2020-07-09 05:44:47] christopher dot broadbent at zencontrol dot com Description: ------------ We're currently hitting a fairly random segfault inside PHP. It's reproducible on each run, but we're having difficulty making a minimal reproduction case to upload here. The builds we're using are from https://deb.sury.org/, but we're also hitting the problem on the builds from docker.io I have a capture running under the rr debugger, and have the first free with a backtrace of #0 zend_mm_free_small (bin_num=<optimized out>, ptr=0x7ff047a6caf0, heap=<optimized out>) at ./Zend/zend_alloc.c:1279 #1 zend_mm_free_heap (ptr=0x7ff047a6caf0, heap=<optimized out>) at ./Zend/zend_alloc.c:1370 #2 _efree (ptr=0x7ff047a6caf0) at ./Zend/zend_alloc.c:2550 #3 0x000056422fc1cb24 in zend_objects_store_del (object=0x7ff047a6cb18) at ./Zend/zend_objects_API.c:197 #4 0x000056422fc6c92f in zend_object_release (obj=<optimized out>) at ./Zend/zend_objects_API.h:75 #5 ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at ./Zend/zend_vm_execute.h:1767 #6 execute_ex (ex=0x7ff047a6caf0) at ./Zend/zend_vm_execute.h:53830 #7 0x000056422fc6da71 in zend_execute (op_array=0x7ff04a27f2a0, return_value=<optimized out>) at ./Zend/zend_vm_execute.h:57922 #8 0x000056422fbe74b3 in zend_execute_scripts (type=type@entry=0x8, retval=0x7ff04a21ca80, retval@entry=0x0, file_count=file_count@entry=0x3) at ./Zend/zend.c:1672 #9 0x000056422fb86b70 in php_execute_script (primary_file=<optimized out>) at ./main/main.c:2621 #10 0x000056422fc6fb86 in do_cli (argc=0xb, argv=0x564230f0cf40) at ./sapi/cli/php_cli.c:961 #11 0x000056422fa4e96b in main (argc=0xb, argv=0x564230f0cf40) at ./sapi/cli/php_cli.c:1356 and the double free has a backtrace of #0 0x000056422fbc1e4b in zend_mm_free_small (bin_num=<optimized out>, ptr=0x7ff047a6caf0, heap=0x7ff04a200040) at ./Zend/zend_alloc.c:1278 #1 zend_mm_free_heap (ptr=0x7ff047a6caf0, heap=0x7ff04a200040) at ./Zend/zend_alloc.c:1370 #2 _efree (ptr=0x7ff047a6caf0) at ./Zend/zend_alloc.c:2550 #3 0x000056422fac9ce4 in zend_string_release (s=<optimized out>) at ./ext/reflection/php_reflection.c:225 #4 reflection_free_objects_storage (object=0x7ff047a6cb18) at ./ext/reflection/php_reflection.c:230 #5 0x000056422fc1cb66 in zend_objects_store_del (object=0x7ff047a6cb18) at ./Zend/zend_objects_API.c:193 #6 0x000056422fc6c92f in zend_object_release (obj=<optimized out>) at ./Zend/zend_objects_API.h:75 #7 ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at ./Zend/zend_vm_execute.h:1767 #8 execute_ex (ex=0x7ff047a6caf0) at ./Zend/zend_vm_execute.h:53830 #9 0x000056422fc6da71 in zend_execute (op_array=0x7ff04a27f2a0, return_value=<optimized out>) at ./Zend/zend_vm_execute.h:57922 #10 0x000056422fbe74b3 in zend_execute_scripts (type=type@entry=0x8, retval=0x7ff04a21ca80, retval@entry=0x0, file_count=file_count@entry=0x3) at ./Zend/zend.c:1672 #11 0x000056422fb86b70 in php_execute_script (primary_file=<optimized out>) at ./main/main.c:2621 #12 0x000056422fc6fb86 in do_cli (argc=0xb, argv=0x564230f0cf40) at ./sapi/cli/php_cli.c:961 #13 0x000056422fa4e96b in main (argc=0xb, argv=0x564230f0cf40) at ./sapi/cli/php_cli.c:1356 This sticks the heap in to a state where (rr) p $heap->free_slot[8] $59 = (zend_mm_free_slot *) 0x7ff047a6caf0 (rr) p $heap->free_slot[8]->next_free_slot $60 = (zend_mm_free_slot *) 0x7ff047a6caf0 (rr) p $heap->free_slot[8]->next_free_slot->next_free_slot $61 = (zend_mm_free_slot *) 0x7ff047a6caf0 etc, and ends up segfaulting on the second-next allocation Running under valgrind gives a double free in a sightly different place: USE_ZEND_ALLOC=0 valgrind -- php our_args outputs a lot of..stuff before eventually crashing with ==29090== Invalid free() / delete / delete[] / realloc() ==29090== at 0x48369AB: free (vg_replace_malloc.c:530) ==29090== by 0x28ACE3: zend_string_release (zend_string.h:277) ==29090== by 0x28ACE3: reflection_free_objects_storage (php_reflection.c:230) ==29090== by 0x3DDB65: zend_objects_store_del (zend_objects_API.c:193) ==29090== by 0x42D92E: zend_object_release (zend_objects_API.h:75) ==29090== by 0x42D92E: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1767) ==29090== by 0x42D92E: execute_ex (zend_vm_execute.h:53830) ==29090== by 0x42EA70: zend_execute (zend_vm_execute.h:57922) ==29090== by 0x3A84B2: zend_execute_scripts (zend.c:1672) ==29090== by 0x347B6F: php_execute_script (main.c:2621) ==29090== by 0x430B85: do_cli (php_cli.c:961) ==29090== by 0x20F96A: main (php_cli.c:1356) ==29090== Address 0xc432c40 is 0 bytes inside a block of size 80 free'd ==29090== at 0x48369AB: free (vg_replace_malloc.c:530) ==29090== by 0x3E3E64: zend_string_release (zend_string.h:277) ==29090== by 0x3E3E64: zend_resolve_class_type (zend_execute.c:947) ==29090== by 0x410B64: i_zend_check_property_type (zend_execute.c:961) ==29090== by 0x410B64: i_zend_verify_property_type (zend_execute.c:984) ==29090== by 0x410B64: zend_verify_property_type (zend_execute.c:993) ==29090== by 0x3DBA85: zend_std_write_property (zend_object_handlers.c:897) ==29090== by 0x3B244E: zend_update_property_ex (zend_API.c:4115) ==29090== by 0x289C4B: zim_reflection_property_setValue (php_reflection.c:5485) ==29090== by 0x42DE5F: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1618) ==29090== by 0x42DE5F: execute_ex (zend_vm_execute.h:53826) ==29090== by 0x42EA70: zend_execute (zend_vm_execute.h:57922) ==29090== by 0x3A84B2: zend_execute_scripts (zend.c:1672) ==29090== by 0x347B6F: php_execute_script (main.c:2621) ==29090== by 0x430B85: do_cli (php_cli.c:961) ==29090== by 0x20F96A: main (php_cli.c:1356) ==29090== Block was alloc'd at ==29090== at 0x483577F: malloc (vg_replace_malloc.c:299) ==29090== by 0x37EF38: __zend_malloc (zend_alloc.c:2976) ==29090== by 0x38629B: zend_string_alloc (zend_string.h:133) ==29090== by 0x38629B: zend_concat3 (zend_compile.c:791) ==29090== by 0x387243: zend_compile_typename (zend_compile.c:5318) ==29090== by 0x38BF6F: zend_compile_prop_decl (zend_compile.c:6100) ==29090== by 0x393EF0: zend_compile_prop_group (zend_compile.c:6178) ==29090== by 0x393EF0: zend_compile_stmt (zend_compile.c:8538) ==29090== by 0x394E46: zend_compile_stmt_list (zend_compile.c:5262) ==29090== by 0x394E46: zend_compile_stmt_list (zend_compile.c:5257) ==29090== by 0x393D59: zend_compile_stmt (zend_compile.c:8479) ==29090== by 0x395BDD: zend_compile_class_decl (zend_compile.c:6467) ==29090== by 0x396AA6: zend_compile_top_stmt (zend_compile.c:8454) ==29090== by 0x396ACF: zend_compile_top_stmt (zend_compile.c:8443) ==29090== by 0x36E844: zend_compile (zend_language_scanner.l:614) I can probably get the full run from the rr debugger uploaded, as well as the valgrind logs, if needed $ php -m [PHP Modules] amqp bcmath calendar Core ctype curl date dom exif FFI fileinfo filter ftp gettext hash iconv intl json libxml mbstring mysqli mysqlnd openssl pcntl pcre PDO pdo_mysql Phar posix rdkafka readline redis Reflection session shmop SimpleXML sockets sodium SPL standard sysvmsg sysvsem sysvshm tokenizer xml xmlreader xmlwriter xsl Zend OPcache zlib [Zend Modules] Zend OPcache ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=79820&edit=1

« previous php.bugs (#228016) next »