Bug #71201 [Ver]: round() segfault on 64-bit builds

From: Date: Wed, 23 Dec 2015 16:50:46 +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-198175@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: ab@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: Ups, i meant abs(), not pow() is the issue. Thanks. Previous Comments: ------------------------------------------------------------------------ [2015-12-23 16:49:33] jpauli@php.net Opening to public, this is not security related ------------------------------------------------------------------------ [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

« previous php.bugs (#198175) next »