php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71824 null ptr deref _zval_get_string_func (zend_operators.c:851)
Submitted: 2016-03-14 16:11 UTC Modified: 2016-03-17 04:28 UTC
From: brian dot carpenter at gmail dot com Assigned: laruence (profile)
Status: Closed Package: Reproducible crash
PHP Version: 7.0Git-2016-03-14 (Git) OS: Debian 8.2 x64
Private report: No CVE-ID: None
 [2016-03-14 16:11 UTC] brian dot carpenter at gmail dot com
Description:
------------
While fuzzing PHP 7.1.0-dev (cli) (built: Mar 13 2016 19:25:22) with American Fuzzy Lop, a script was found to trigger a null ptr deref and cause a segfault. 

Test script:
---------------
<?php
$e0pl0it='O:10:"0000000000":1:0s:8:"00000000"0a:1:{s:8:"00000000"0a:3:{i:0;s:0:"";i:0;N;i:0;N;}}}';$z=unserialize($e0pl0it);$z->e.=0;t('','');

Expected result:
----------------
PHP 5.4.45-0+deb7u2 errors out with the following message:

PHP Notice:  main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "0000000000" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in /home/geeknik/test01 on line 2
PHP Fatal error:  Call to undefined function t() in /home/geeknik/test00 on line 2

Actual result:
--------------
==114748== Invalid read of size 8
==114748==    at 0x1427048: _zval_get_string_func (zend_operators.c:851)
==114748==    by 0x1449753: zend_make_printable_zval (zend.c:249)
==114748==    by 0x141CE10: concat_function (zend_operators.c:1605)
==114748==    by 0x17CCAC4: zend_binary_assign_op_obj_helper_SPEC_CV_CONST (zend_vm_execute.h:36303)
==114748==    by 0x1614532: execute_ex (zend_vm_execute.h:423)
==114748==    by 0x187E654: zend_execute (zend_vm_execute.h:467)
==114748==    by 0x14510D7: zend_execute_scripts (zend.c:1427)
==114748==    by 0x11FFE8F: php_execute_script (main.c:2487)
==114748==    by 0x18878E0: do_cli (php_cli.c:974)
==114748==    by 0x4507F0: main (php_cli.c:1345)
==114748==  Address 0x1d0 is not stack'd, malloc'd or (recently) free'd
==114748== 
==114748== 
==114748== Process terminating with default action of signal 11 (SIGSEGV)
==114748==  Access not within mapped region at address 0x1D0
==114748==    at 0x1427048: _zval_get_string_func (zend_operators.c:851)
==114748==    by 0x1449753: zend_make_printable_zval (zend.c:249)
==114748==    by 0x141CE10: concat_function (zend_operators.c:1605)
==114748==    by 0x17CCAC4: zend_binary_assign_op_obj_helper_SPEC_CV_CONST (zend_vm_execute.h:36303)
==114748==    by 0x1614532: execute_ex (zend_vm_execute.h:423)
==114748==    by 0x187E654: zend_execute (zend_vm_execute.h:467)
==114748==    by 0x14510D7: zend_execute_scripts (zend.c:1427)
==114748==    by 0x11FFE8F: php_execute_script (main.c:2487)
==114748==    by 0x18878E0: do_cli (php_cli.c:974)
==114748==    by 0x4507F0: main (php_cli.c:1345)
==114748==  If you believe this happened as a result of a stack
==114748==  overflow in your program's main thread (unlikely but
==114748==  possible), you can try to increase the size of the
==114748==  main thread stack using the --main-stacksize= flag.
==114748==  The main thread stack size used in this run was 8388608.
Segmentation fault

(gdb) r test00
Starting program: /home/geeknik/php-src/sapi/cli/php test00
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000000001427048 in _zval_get_string_func (
    op=op@entry=0x20166d0 <executor_globals+16>)
    at /home/geeknik/php-src/Zend/zend_operators.c:851
851				zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(op)->name));
(gdb) list
846						zval_ptr_dtor(z);
847						return str;
848					}
849					zval_ptr_dtor(z);
850				}
851				zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(op)->name));
852				return ZSTR_EMPTY_ALLOC();
853			}
854			case IS_REFERENCE:
855				op = Z_REFVAL_P(op);
(gdb) bt
#0  0x0000000001427048 in _zval_get_string_func (
    op=op@entry=0x20166d0 <executor_globals+16>)
    at /home/geeknik/php-src/Zend/zend_operators.c:851
#1  0x0000000001449754 in zend_make_printable_zval (
    expr=expr@entry=0x20166d0 <executor_globals+16>, 
    expr_copy=expr_copy@entry=0x7fffffffa830)
    at /home/geeknik/php-src/Zend/zend.c:249
#2  0x000000000141ce11 in concat_function (result=<optimized out>, 
    op1=0x20166d0 <executor_globals+16>, op2=0x7ffff60770d0)
    at /home/geeknik/php-src/Zend/zend_operators.c:1605
#3  0x00000000017ccac5 in zend_binary_assign_op_obj_helper_SPEC_CV_CONST (
    binary_op=0x141c660 <concat_function>)
    at /home/geeknik/php-src/Zend/zend_vm_execute.h:36303
#4  0x0000000001614533 in execute_ex (ex=<optimized out>)
    at /home/geeknik/php-src/Zend/zend_vm_execute.h:423
#5  0x000000000187e655 in zend_execute (
    op_array=op_array@entry=0x7ffff60870a0, 
    return_value=return_value@entry=0x0)
    at /home/geeknik/php-src/Zend/zend_vm_execute.h:467
#6  0x00000000014510d8 in zend_execute_scripts (type=type@entry=8, 
    retval=retval@entry=0x0, file_count=-167694288, file_count@entry=3)
    at /home/geeknik/php-src/Zend/zend.c:1427
#7  0x00000000011ffe90 in php_execute_script (primary_file=0x7fffffffcf10)
    at /home/geeknik/php-src/main/main.c:2487
#8  0x00000000018878e1 in do_cli (argc=33646288, argv=0x7fffffffa830)
    at /home/geeknik/php-src/sapi/cli/php_cli.c:974
#9  0x00000000004507f1 in main (argc=33646288, argv=0x7fffffffa830)
    at /home/geeknik/php-src/sapi/cli/php_cli.c:1345


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-15 09:00 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2016-03-15 23:13 UTC] nikic@php.net
There's two distinct bug here. The first one causing the segfault can be reduced to

$obj = unserialize('O:1:"A":0:{}');
var_dump($obj);
$obj->prop .= 0;

The issue is that get_property_ptr_ptr return EG(error_zval) instead of NULL (at least that should do it for PHP 7).

The second issue is that

var_dump(unserialize('a:1:{s:0:""0a:0:{}}'));
                                 ^-- wrong

does not fail. That 0 should be a semicolon. We should not be accepting this string.
 [2016-03-17 03:57 UTC] laruence@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b9aed47a7a9a1e9485317b5b0d5c58ff4cec5456
Log: Fixed Bug #71824 (null ptr deref _zval_get_string_func (zend_operators.c:851))
 [2016-03-17 03:57 UTC] laruence@php.net
-Status: Assigned +Status: Closed
 [2016-03-17 04:28 UTC] laruence@php.net
thanks nikic, the part 1 is fixed, part 2, I opened a new bug entry #71840
 [2016-04-18 09:29 UTC] bwoebi@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b9aed47a7a9a1e9485317b5b0d5c58ff4cec5456
Log: Fixed Bug #71824 (null ptr deref _zval_get_string_func (zend_operators.c:851))
 [2016-07-20 11:32 UTC] davey@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b9aed47a7a9a1e9485317b5b0d5c58ff4cec5456
Log: Fixed Bug #71824 (null ptr deref _zval_get_string_func (zend_operators.c:851))
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Tue Dec 18 18:01:27 2018 UTC