php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72789 closure casting causes use after free
Submitted: 2016-08-09 00:47 UTC Modified: 2017-12-28 17:31 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: fernando at null-life dot com Assigned: nikic (profile)
Status: Closed Package: Reproducible crash
PHP Version: 5.6.24 OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: fernando at null-life dot com
New email:
PHP Version: OS:

 

 [2016-08-09 00:47 UTC] 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


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-08-10 06:17 UTC] stas@php.net
-Type: Security +Type: Bug
 [2017-12-28 17:31 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2017-12-28 17:31 UTC] nikic@php.net
Both POCs do not reproduce in PHP 7, so I'm assuming that this is fixed.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 03:01:32 2025 UTC