Bug #71201 [Ver]: round() segfault on 64-bit builds
| From: | jpauli@php.net | Date: | Wed, 23 Dec 2015 16:49:33 +0000 |
| Subject: | Bug #71201 [Ver]: round() segfault on 64-bit builds | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-198174@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=71201&edit=1
ID: 71201
Updated by: jpauli@php.net
Reported by: andrew at jmpesp dot org
Summary: round() segfault on 64-bit builds
Status: Verified
Type: Bug
Package: Scripting Engine problem
Operating System: Linux
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
Opening to public, this is not security related
Previous Comments:
------------------------------------------------------------------------
[2015-12-23 16:44:11] 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:29:27] ab@php.net
Thanks for the report. Bug confirmed. But i don't think it is a security issue.
Thanks.
------------------------------------------------------------------------
[2015-12-23 08:38:11] 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);
?>
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=71201&edit=1