Bug #72789 [Opn->Csd]: closure casting causes use after free

From: Date: Thu, 28 Dec 2017 17:31:03 +0000
Subject: Bug #72789 [Opn->Csd]: closure casting causes use after free
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-213311@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72789&edit=1 ID: 72789 Updated by: nikic@php.net Reported by: fernando at null-life dot com Summary: closure casting causes use after free -Status: Open +Status: Closed Type: Bug Package: Reproducible crash Operating System: * PHP Version: 5.6.24 -Assigned To: +Assigned To: nikic Block user comment: N Private report: N New Comment: Both POCs do not reproduce in PHP 7, so I'm assuming that this is fixed. Previous Comments: ------------------------------------------------------------------------ [2016-08-09 00:47:35] fernando at null-life dot com Description: ------------ Use after free is caused when closure objects are casted to strings. It's necessary to continue recoverable exception for it to happen. Source code: https://github.com/php/php-src/blob/PHP-5.6.24/Zend/zend_operators.c#L640 ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */ { long lval; double dval; switch (Z_TYPE_P(op)) { ... case IS_OBJECT: { TSRMLS_FETCH(); convert_object_to_type(op, IS_STRING, convert_to_string); if (Z_TYPE_P(op) == IS_STRING) { return; } zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name); zval_dtor(op); Z_STRVAL_P(op) = estrndup_rel("Object", sizeof("Object")-1); Z_STRLEN_P(op) = sizeof("Object")-1; break; ... Test script: --------------- poc1: <?php function myErrorHandler($errno, $errstr, $errfile, $errline) { if ( E_RECOVERABLE_ERROR===$errno ) { return true; } return false; } set_error_handler('myErrorHandler'); $f = function() { return 0; }; $r = NULL; openssl_pkcs12_export($f, $r, "", ""); var_dump($f); poc2.php: <?php function myErrorHandler($errno, $errstr, $errfile, $errline) { if ( E_RECOVERABLE_ERROR===$errno ) { return true; } return false; } set_error_handler('myErrorHandler'); $f = function() { return 0; }; spl_autoload_register($f); mb_detect_encoding("encoding", $f); get_class_vars("class"); Expected result: ---------------- No crash Actual result: -------------- POC1 ==13079==ERROR: AddressSanitizer: heap-use-after-free on address 0x60300004cbb5 at pc 0x000001bfad5e bp 0x7ffd5de44d10 sp 0x7ffd5de44d00 READ of size 1 at 0x60300004cbb5 thread T0 #0 0x1bfad5d in zend_send_by_var_helper_SPEC_CV /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:31209 #1 0x1c0463c in execute_ex /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:363 #2 0x194c382 in zend_execute_scripts /home/operac/build2/php-src-56/Zend/zend.c:1341 #3 0x169a2df in php_execute_script /home/operac/build2/php-src-56/main/main.c:2613 #4 0x1d64366 in do_cli /home/operac/build2/php-src-56/sapi/cli/php_cli.c:994 #5 0x4550a0 in main /home/operac/build2/php-src-56/sapi/cli/php_cli.c:1378 #6 0x7fee9943282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #7 0x4556b8 in _start (/home/operac/build2/bin/php+0x4556b8) 0x60300004cbb5 is located 21 bytes inside of 32-byte region [0x60300004cba0,0x60300004cbc0) freed by thread T0 here: #0 0x7fee9b9fc2ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca) #1 0x1d58f64 in i_zval_ptr_dtor /home/operac/build2/php-src-56/Zend/zend_execute.h:80 #2 0x1d58f64 in zend_vm_stack_clear_multiple /home/operac/build2/php-src-56/Zend/zend_execute.h:308 #3 0x1d58f64 in zend_do_fcall_common_helper_SPEC /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:650 #4 0x1c0463c in execute_ex /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:363 #5 0x194c382 in zend_execute_scripts /home/operac/build2/php-src-56/Zend/zend.c:1341 #6 0x169a2df in php_execute_script /home/operac/build2/php-src-56/main/main.c:2613 #7 0x1d64366 in do_cli /home/operac/build2/php-src-56/sapi/cli/php_cli.c:994 #8 0x4550a0 in main /home/operac/build2/php-src-56/sapi/cli/php_cli.c:1378 #9 0x7fee9943282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) previously allocated by thread T0 here: #0 0x7fee9b9fc602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x1ac3e2a in zend_assign_tmp_to_variable /home/operac/build2/php-src-56/Zend/zend_execute.c:849 #2 0x1ac4476 in ZEND_ASSIGN_SPEC_CV_TMP_HANDLER /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:35523 #3 0x1c0463c in execute_ex /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:363 #4 0x194c382 in zend_execute_scripts /home/operac/build2/php-src-56/Zend/zend.c:1341 #5 0x169a2df in php_execute_script /home/operac/build2/php-src-56/main/main.c:2613 #6 0x1d64366 in do_cli /home/operac/build2/php-src-56/sapi/cli/php_cli.c:994 #7 0x4550a0 in main /home/operac/build2/php-src-56/sapi/cli/php_cli.c:1378 #8 0x7fee9943282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) SUMMARY: AddressSanitizer: heap-use-after-free /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:31209 zend_send_by_var_helper_SPEC_CV POC2 ==13091==ERROR: AddressSanitizer: heap-use-after-free on address 0x612000005778 at pc 0x0000018d28f2 bp 0x7ffea0002870 sp 0x7ffea0002860 READ of size 4 at 0x612000005778 thread T0 #0 0x18d28f1 in zend_call_function /home/operac/build2/php-src-56/Zend/zend_execute_API.c:706 #1 0x19f9868 in zend_call_method /home/operac/build2/php-src-56/Zend/zend_interfaces.c:97 #2 0x11a8f1a in zif_spl_autoload_call /home/operac/build2/php-src-56/ext/spl/php_spl.c:436 #3 0x18d0503 in zend_call_function /home/operac/build2/php-src-56/Zend/zend_execute_API.c:847 #4 0x18d5285 in zend_lookup_class_ex /home/operac/build2/php-src-56/Zend/zend_execute_API.c:1005 #5 0x19def65 in zif_get_class_vars /home/operac/build2/php-src-56/Zend/zend_builtin_functions.c:971 #6 0x1d5b393 in zend_do_fcall_common_helper_SPEC /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:558 #7 0x1c0463c in execute_ex /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:363 #8 0x194c382 in zend_execute_scripts /home/operac/build2/php-src-56/Zend/zend.c:1341 #9 0x169a2df in php_execute_script /home/operac/build2/php-src-56/main/main.c:2613 #10 0x1d64366 in do_cli /home/operac/build2/php-src-56/sapi/cli/php_cli.c:994 #11 0x4550a0 in main /home/operac/build2/php-src-56/sapi/cli/php_cli.c:1378 #12 0x7fdc66c2a82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #13 0x4556b8 in _start (/home/operac/build2/bin/php+0x4556b8) 0x612000005778 is located 56 bytes inside of 296-byte region [0x612000005740,0x612000005868) freed by thread T0 here: #0 0x7fdc691f42ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca) #1 0x1a8a83f in zend_objects_store_del_ref_by_handle_ex /home/operac/build2/php-src-56/Zend/zend_objects_API.c:226 #2 0x1a8acad in zend_objects_store_del_ref /home/operac/build2/php-src-56/Zend/zend_objects_API.c:178 #3 0x18fa5f8 in _zval_dtor /home/operac/build2/php-src-56/Zend/zend_variables.h:35 #4 0x18fa5f8 in _convert_to_string /home/operac/build2/php-src-56/Zend/zend_operators.c:650 #5 0xdc5d10 in zif_mb_detect_encoding /home/operac/build2/php-src-56/ext/mbstring/mbstring.c:3237 #6 0x1d5b393 in zend_do_fcall_common_helper_SPEC /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:558 #7 0x1c0463c in execute_ex /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:363 #8 0x194c382 in zend_execute_scripts /home/operac/build2/php-src-56/Zend/zend.c:1341 #9 0x169a2df in php_execute_script /home/operac/build2/php-src-56/main/main.c:2613 #10 0x1d64366 in do_cli /home/operac/build2/php-src-56/sapi/cli/php_cli.c:994 #11 0x4550a0 in main /home/operac/build2/php-src-56/sapi/cli/php_cli.c:1378 #12 0x7fdc66c2a82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) previously allocated by thread T0 here: #0 0x7fdc691f4602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x1a362ac in zend_closure_new /home/operac/build2/php-src-56/Zend/zend_closures.c:287 #2 0x1959ed0 in _object_and_properties_init /home/operac/build2/php-src-56/Zend/zend_API.c:1199 #3 0x1a380c0 in zend_create_closure /home/operac/build2/php-src-56/Zend/zend_closures.c:461 #4 0x1a9d143 in ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:6820 #5 0x1c0463c in execute_ex /home/operac/build2/php-src-56/Zend/zend_vm_execute.h:363 #6 0x194c382 in zend_execute_scripts /home/operac/build2/php-src-56/Zend/zend.c:1341 #7 0x169a2df in php_execute_script /home/operac/build2/php-src-56/main/main.c:2613 #8 0x1d64366 in do_cli /home/operac/build2/php-src-56/sapi/cli/php_cli.c:994 #9 0x4550a0 in main /home/operac/build2/php-src-56/sapi/cli/php_cli.c:1378 #10 0x7fdc66c2a82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) SUMMARY: AddressSanitizer: heap-use-after-free /home/operac/build2/php-src-56/Zend/zend_execute_API.c:706 zend_call_function ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72789&edit=1

« previous php.bugs (#213311) next »