php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71201 round() segfault on 64-bit builds
Submitted: 2015-12-23 08:38 UTC Modified: 2015-12-23 17:35 UTC
From: andrew at jmpesp dot org Assigned: ab (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: andrew at jmpesp dot org
New email:
PHP Version: OS:

 

 [2015-12-23 08:38 UTC] andrew at jmpesp dot org
Description:
------------
Supplying a large negative number as the second parameter to round() reliably produces a segmentation fault.  Tested on Linux with both v7.0.0 and v5.6.16.  This issue appears to only affect 64-bit builds.

Due to the limited range of values which cause a crash I do not believe this issue is exploitable.  However given the nature of the crash (out of bounds read) I am classifying this as "security" just in case.  I'll let you smart people make that call.


Here's some gdb output that may be helpful to you...
====================================================
(gdb) r -r 'echo round(1.0, -2147483648);'
Starting program: /tmp/php-7.0.1/sapi/cli/php -r 'echo round(1, -2147483648);'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000000000628fe7 in php_intpow10 (power=-2147483648) at /tmp/php-7.0.1/ext/standard/math.c:93
93		return powers[power];
(gdb) i r
rax            0xffffffff80000000	-2147483648
rbx            0x80000000	2147483648
rcx            0xb5f5c0	11924928
rdx            0xb5f500	11924736
rsi            0x9	9
rdi            0x80000000	2147483648
rbp            0x1	0x1
rsp            0x7fffffffc8c0	0x7fffffffc8c0
r8             0x0	0
r9             0x0	0
r10            0x1	1
r11            0x1	1
r12            0xe	14
r13            0x7ffff60120a0	140737320657056
r14            0x7ffff6012030	140737320656944
r15            0x7ffff6070360	140737321042784
rip            0x628fe7	0x628fe7 <_php_math_round+279>
eflags         0x10a12	[ AF IF OF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) x/1i $rip
=> 0x628fe7 <_php_math_round+279>:	movsd  xmm5,QWORD PTR [rdx+rax*8]
(gdb) bt
#0  0x0000000000628fe7 in php_intpow10 (power=-2147483648) at /tmp/php-7.0.1/ext/standard/math.c:93
#1  _php_math_round (value=1, places=-2147483648, mode=1) at /tmp/php-7.0.1/ext/standard/math.c:152
#2  0x0000000000629916 in zif_round (execute_data=0x7ffff60120a0, return_value=0x7ffff6012090) at /tmp/php-7.0.1_32/ext/standard/math.c:408
#3  0x000000000071796d in ZEND_DO_ICALL_SPEC_HANDLER () at /tmp/php-7.0.1/Zend/zend_vm_execute.h:586
#4  0x0000000000708e0b in execute_ex (ex=<optimized out>) at /tmp/php-7.0.1/Zend/zend_vm_execute.h:414
#5  0x000000000075ad47 in zend_execute (op_array=op_array@entry=0x7ffff607c000, return_value=return_value@entry=0x7fffffffca50)
    at /tmp/php-7.0.1/Zend/zend_vm_execute.h:458
#6  0x00000000006beb77 in zend_eval_stringl (str=0x7ffff6012030 "`\003\a\366\377\177", str@entry=0xec02a0 "echo round(1, -2147483648);", 
    str_len=<optimized out>, retval_ptr=retval_ptr@entry=0x0, string_name=string_name@entry=0xb853df "Command line code")
    at /tmp/php-7.0.1/Zend/zend_execute_API.c:1125
#7  0x00000000006bec49 in zend_eval_stringl_ex (str=str@entry=0xec02a0 "echo round(1, -2147483648);", str_len=<optimized out>, 
    retval_ptr=retval_ptr@entry=0x0, string_name=string_name@entry=0xb853df "Command line code", handle_exceptions=handle_exceptions@entry=1)
    at /tmp/php-7.0.1/Zend/zend_execute_API.c:1166
#8  0x00000000006becb9 in zend_eval_string_ex (str=str@entry=0xec02a0 "echo round(1, -2147483648);", retval_ptr=retval_ptr@entry=0x0, 
    string_name=string_name@entry=0xb853df "Command line code", handle_exceptions=handle_exceptions@entry=1)
    at /tmp/php-7.0.1/Zend/zend_execute_API.c:1177
#9  0x000000000075c76c in do_cli (argc=3, argv=0xec0220) at /tmp/php-7.0.1/sapi/cli/php_cli.c:1005
#10 0x0000000000429718 in main (argc=3, argv=0xec0220) at /tmp/php-7.0.1/sapi/cli/php_cli.c:1345
(gdb) 



Test script:
---------------
<?php
echo round(1.0, -2147483648);
?>


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-12-23 16:29 UTC] ab@php.net
-Status: Open +Status: Verified
 [2015-12-23 16:29 UTC] ab@php.net
Thanks for the report. Bug confirmed. But i don't think it is a security issue.

Thanks.
 [2015-12-23 16:44 UTC] ab@php.net
The Linux pow() function seems to be sensitive to the overflowed values. Please check the patch below (against 7.0)

diff --git a/ext/standard/math.c b/ext/standard/math.c
index 6059f3d..e79817e 100644
--- a/ext/standard/math.c
+++ b/ext/standard/math.c
@@ -390,7 +390,11 @@ PHP_FUNCTION(round)
        }

        if (ZEND_NUM_ARGS() >= 2) {
-               places = (int) precision;
+               if (precision >= 0) {
+                       places = precision > INT_MAX ? INT_MAX : (int)precision;
+               } else {
+                       places = precision <= INT_MIN ? INT_MIN+1 : (int)precision;
+               }
        }
        convert_scalar_to_number_ex(value);

Thanks
 [2015-12-23 16:48 UTC] jpauli@php.net
-Type: Security +Type: Bug
 [2015-12-23 16:49 UTC] jpauli@php.net
Opening to public, this is not security related
 [2015-12-23 16:50 UTC] ab@php.net
Ups, i meant abs(), not pow() is the issue.

Thanks.
 [2015-12-23 17:35 UTC] ab@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: ab
 [2015-12-23 17:35 UTC] ab@php.net
Fixed in 0d822f6df946764f3f0348b82efae2e1eaa83aa0. Ttahnks.
 [2016-02-11 16:54 UTC] hui at pizda dot eba
php хуйня ебаная
 [2016-10-01 16:33 UTC] spam2 at rhsoft dot net
when building with -O3 and Profile-Guided Optimization (make prof-gen; <run-php-code>; make prof-clean; make prof-use" this crash comes back

add -fwrapv to CCFLAGS and nothing else changed and it's fixed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63358#c1
_______________________________

in fact it happens only with profile-guided-optimization, otherwise the flags below without -fwrapv don't have this crash

- final php7 compiler-flags for documentation purpose
- '-m64 -O3 -g0 -fopenmp -mfpmath=sse -pipe -fomit-frame-pointer -finline-functions -fexceptions -fstack-protector-strong --param=ssp-buffer-size=8 -D_FORTIFY_SOURCE=2 -Wstack-protector -Wformat -Werror=format-security -fira-loop-pressure -fivopts -fmerge-all-constants -fstrict-aliasing -ftree-loop-distribution -ftree-loop-if-convert -ftree-loop-ivcanon -ftree-slp-vectorize -ftree-vectorize -funroll-loops -fwrapv -minline-all-stringops -fno-align-labels -fno-gcse -fno-math-errno -Wno-pointer-sign -Wno-stack-protector'
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC