php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69815 null ptr deref and seg fault in convert_to_long_base (zend_operators.c:303)
Submitted: 2015-06-12 20:48 UTC Modified: 2015-06-16 18:08 UTC
From: brian dot carpenter at gmail dot com Assigned: nikic (profile)
Status: Closed Package: Reproducible crash
PHP Version: 7.0Git-2015-06-12 (Git) OS: Debian 7
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: brian dot carpenter at gmail dot com
New email:
PHP Version: OS:

 

 [2015-06-12 20:48 UTC] brian dot carpenter at gmail dot com
Description:
------------
While fuzzing PHP 7 built from git source with AFL (http://lcamtuf.coredump.cx/afl/), I discoved a script that causes a null ptr deref and a seg fault in convert_to_long_base (zend_operators.c:303). 

Test script:
---------------
<?php
class SplMinHeap0 extends SplMinHeap{public function&compare($b){return$t;}}$h=new SplMinHeap0;$h->insert(0);$h->insert(0)?>

Expected result:
----------------
No crash. Supplied code runs w/o error with PHP 5.4.41-0+deb7u1.

Actual result:
--------------
Program received signal SIGSEGV, Segmentation fault.
0x00000000013ecb24 in convert_to_long_base () at /home/geeknik/php-src/Zend/zend_operators.c:303
303				ZVAL_LONG(op, zend_dval_to_lval(Z_DVAL_P(op)));
(gdb) bt
#0  0x00000000013ecb24 in convert_to_long_base () at /home/geeknik/php-src/Zend/zend_operators.c:303
#1  0x0000000000ed940a in spl_ptr_heap_zval_min_cmp ()
#2  0x0000000000ed374a in spl_ptr_heap_insert ()
#3  0x0000000000ed3b59 in zim_spl_SplHeap_insert ()
#4  0x00000000017e73f9 in ZEND_DO_FCALL_SPEC_HANDLER ()
#5  0x00000000015daa93 in execute_ex ()
#6  0x00000000018006a5 in zend_execute ()
#7  0x000000000141027c in zend_execute_scripts ()
#8  0x00000000011c2a20 in php_execute_script ()
#9  0x0000000001807d05 in do_cli () at /home/geeknik/php-src/sapi/cli/php_cli.c:967
#10 0x000000000043c021 in main () at /home/geeknik/php-src/sapi/cli/php_cli.c:1334
(gdb) i r
rax            0x0	0
rbx            0x1	1
rcx            0x0	0
rdx            0x55	85
rsi            0xa	10
rdi            0x7fffffffa800	140737488332800
rbp            0x1fd4440	0x1fd4440
rsp            0x7fffffffa7b0	0x7fffffffa7b0
r8             0x7ffff6013110	140737320661264
r9             0x20	32
r10            0x7ffff6055500	140737320932608
r11            0x7fffffffa620	140737488332320
r12            0x7fffffffa800	140737488332800
r13            0x7ffff6013130	140737320661296
r14            0x0	0
r15            0x7ffff6001150	140737320587600
rip            0x13ecb24	0x13ecb24 <convert_to_long_base+1316>
eflags         0x10202	[ IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-06-12 20:59 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 [2015-06-12 20:59 UTC] nikic@php.net
This issue exists in various forms in many places we use convert_to_*, because it currently does not support references.

My plan is to implement the following behavior:
 * convert_to_* functions will either UNREF if rc=1 or DELREF+DEREF if rc>1 -- this is the same as convert_scalar_to_number
 * convert_to_*_ex function will DEREF and then convert_to_*

So that convert_to drops the reference (which is what you usually want on temporaries), while _ex keeps it and modifies the referenced value.

Also just noticed that the implementation of convert_scalar_to_number looks broken -- http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#147 should probably be ZVAL_COPY.
 [2015-06-16 18:08 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 [2015-06-16 18:08 UTC] nikic@php.net
Fixed by https://github.com/php/php-src/commit/fb346c8f9376d4a0be80e242406c1bb8dbf710f0.

I ended up keeping convert_to_*_ex as an alias of convert_to_* -- we're currently using _ex on things like &retval, which is incompatible with DEREF.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 18:01:29 2024 UTC