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
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: 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 13:01:29 2024 UTC