Edit report at https://bugs.php.net/bug.php?id=65000&edit=1
ID: 65000 Updated by: larue...@php.net Reported by: s...@php.net Summary: use after free (double free) caused by emalloc in _zval_copy_ctor_func Status: Open Type: Bug Package: Reproducible crash Operating System: Linux PHP Version: 5.4.16 Block user comment: N Private report: Y New Comment: here is the replay I wrote to security, just for the record: A fix could be, set the zval type to be NULL, then doing the estrndup, then set it back to IS_STRING: @@ -118,10 +118,12 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC) break; case IS_CONSTANT: case IS_STRING: + ZVAL_NULL(zvalue); CHECK_ZVAL_STRING_REL(zvalue); if (!IS_INTERNED(zvalue->value.str.val)) { zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.l en); } + Z_TYPE_P(zvalue) = IS_STRING; break; but it definitly will brings performance slow down... Previous Comments: ------------------------------------------------------------------------ [2013-06-09 16:05:18] s...@php.net Description: ------------ $ ./php --version PHP 5.4.16 (cli) (built: Jun 9 2013 17:56:24) (DEBUG) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies --- (gdb) r ~shm/php1.php Starting program: /home/fuzzphp/php-5.4.16/sapi/cli/php ~shm/php1.php Fatal error: Allowed memory size of 33554432 bytes exhausted at /home/fuzzphp/php-5.4.16/Zend/zend_vm_execute.h:27134 (tried to allocate 30000001 bytes) in /home/shm/php1.php on line 11 Program received signal SIGSEGV, Segmentation fault. 0x00000000008ebc07 in _zval_dtor_func (zvalue=0x7ffff7fdb4d8, __zend_filename=0xeac8e8 "/home/fuzzphp/php-5.4.16/Zend/zend_execute_API.c", __zend_lineno=438) at /home/fuzzphp/php-5.4.16/Zend/zend_variables.c:35 35 CHECK_ZVAL_STRING_REL(zvalue); (gdb) bt #0 0x00000000008ebc07 in _zval_dtor_func (zvalue=0x7ffff7fdb4d8, __zend_filename=0xeac8e8 "/home/fuzzphp/php-5.4.16/Zend/zend_execute_API.c", __zend_lineno=438) at /home/fuzzphp/php-5.4.16/Zend/zend_variables.c:35 #1 0x00000000008da584 in _zval_dtor (zvalue=0x7ffff7fdb4d8, __zend_filename=0xeac8e8 "/home/fuzzphp/php-5.4.16/Zend/zend_execute_API.c", __zend_lineno=438) at /home/fuzzphp/php-5.4.16/Zend/zend_variables.h:35 #2 0x00000000008db528 in _zval_ptr_dtor (zval_ptr=0x7ffff7fdcb00, __zend_filename=0xeae170 "/home/fuzzphp/php-5.4.16/Zend/zend_variables.c", __zend_lineno=182) at /home/fuzzphp/php-5.4.16/Zend/zend_execute_API.c:438 #3 0x00000000008ec0c1 in _zval_ptr_dtor_wrapper (zval_ptr=0x7ffff7fdcb00) at /home/fuzzphp/php-5.4.16/Zend/zend_variables.c:182 #4 0x000000000090046a in zend_hash_apply_deleter (ht=0x116ad88, p=0x7ffff7fdcae8) at /home/fuzzphp/php-5.4.16/Zend/zend_hash.c:650 #5 0x00000000009005fb in zend_hash_graceful_reverse_destroy (ht=0x116ad88) at /home/fuzzphp/php-5.4.16/Zend/zend_hash.c:687 #6 0x00000000008daed3 in shutdown_executor () at /home/fuzzphp/php-5.4.16/Zend/zend_execute_API.c:247 #7 0x00000000008edf1e in zend_deactivate () at /home/fuzzphp/php-5.4.16/Zend/zend.c:938 #8 0x000000000086438f in php_request_shutdown (dummy=0x0) at /home/fuzzphp/php-5.4.16/main/main.c:1800 #9 0x0000000000990d12 in do_cli (argc=2, argv=0x7fffffffe628) at /home/fuzzphp/php-5.4.16/sapi/cli/php_cli.c:1171 #10 0x0000000000991418 in main (argc=2, argv=0x7fffffffe628) at /home/fuzzphp/php-5.4.16/sapi/cli/php_cli.c:1364 ----- It seems that _zval_copy_ctor_func can be used to trigger double free/use after free issue, in case when emalloc pointed here: http://lxr.php.net/xref/PHP_5_4/Zend/zend_variables.c#123 fails (estrndup calls emalloc internally). The interpreter runs destroy functions on error (memory exhastion) which lead to use value.str.val two times. Please see the test script for details. I'm not sure how to fix the issue, so I left it for smarter than me. :-) Test script: --------------- <?php ini_set('memory_limit', '32M'); $var5 = str_repeat("A",30000000); $x = array($var5); function crash_me(&$x) { die('failed :-('); } crash_me($var5); Expected result: ---------------- no crash Actual result: -------------- SEGFAULT ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=65000&edit=1