mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
ext/gmp: gmp_pow fix FPE with large values.
even without sanitizers, it is reproducible but with the following
```
<?php
$g = gmp_init(256);
var_dump(gmp_pow($g, PHP_INT_MAX));
```
we get this
```
AddressSanitizer:DEADLYSIGNAL
=================================================================
==286922==ERROR: AddressSanitizer: FPE on unknown address 0x03e8000460ca (pc 0x7faf6c69de5c bp 0x400000000000004 sp 0x7ffe9843c740 T0)
#0 0x7faf6c69de5c in __pthread_kill_implementation nptl/pthread_kill.c:44
#1 0x7faf6c649c81 in __GI_raise ../sysdeps/posix/raise.c:26
#2 0x7faf6db9386c in __gmp_exception (/lib/x86_64-linux-gnu/libgmp.so.10+0xd86c) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38)
#3 0x7faf6db938d3 in __gmp_overflow_in_mpz (/lib/x86_64-linux-gnu/libgmp.so.10+0xd8d3) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38)
#4 0x7faf6dbac95c in __gmpz_realloc (/lib/x86_64-linux-gnu/libgmp.so.10+0x2695c) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38)
#5 0x7faf6dba9038 in __gmpz_n_pow_ui (/lib/x86_64-linux-gnu/libgmp.so.10+0x23038) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38)
#6 0x5565ae1ccd9f in zif_gmp_pow /home/dcarlier/Contribs/php-src/ext/gmp/gmp.c:1286
#7 0x5565aee96ea9 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:1312
#8 0x5565af144320 in execute_ex /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:56075
#9 0x5565af160f07 in zend_execute /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:60439
#10 0x5565aed6fafe in zend_execute_scripts /home/dcarlier/Contribs/php-src/Zend/zend.c:1842
#11 0x5565aeae70a8 in php_execute_script /home/dcarlier/Contribs/php-src/main/main.c:2578
#12 0x5565af532f4e in do_cli /home/dcarlier/Contribs/php-src/sapi/cli/php_cli.c:964
#13 0x5565af535877 in main /home/dcarlier/Contribs/php-src/sapi/cli/php_cli.c:1334
#14 0x7faf6c633d67 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#15 0x7faf6c633e24 in __libc_start_main_impl ../csu/libc-start.c:360
#16 0x5565adc04040 in _start (/home/dcarlier/Contribs/php-src/sapi/cli/php+0x2604040) (BuildId: 949049955bdf8b7197390b1978a1dfc3ef6fdf38)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE nptl/pthread_kill.c:44 in __pthread_kill_implementation
==286922==ABORTING
```
This commit is contained in:
4
NEWS
4
NEWS
@@ -21,6 +21,10 @@ PHP NEWS
|
||||
. Fixed bug GH-16334 (imageaffine overflow on matrix elements).
|
||||
(David Carlier)
|
||||
|
||||
- GMP:
|
||||
. Fixed floating point exception bug with gmp_pow when using
|
||||
large exposant values. (David Carlier).
|
||||
|
||||
- MBstring:
|
||||
. Fixed bug GH-16361 (mb_substr overflow on start/length arguments).
|
||||
(David Carlier)
|
||||
|
||||
@@ -1278,12 +1278,37 @@ ZEND_FUNCTION(gmp_pow)
|
||||
|
||||
if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) {
|
||||
INIT_GMP_RETVAL(gmpnum_result);
|
||||
mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp);
|
||||
if (exp >= INT_MAX) {
|
||||
mpz_t base_num, exp_num, mod;
|
||||
mpz_init(base_num);
|
||||
mpz_init(exp_num);
|
||||
mpz_init(mod);
|
||||
mpz_set_si(base_num, Z_LVAL_P(base_arg));
|
||||
mpz_set_si(exp_num, exp);
|
||||
mpz_set_ui(mod, UINT_MAX);
|
||||
mpz_powm(gmpnum_result, base_num, exp_num, mod);
|
||||
mpz_clear(mod);
|
||||
mpz_clear(exp_num);
|
||||
mpz_clear(base_num);
|
||||
} else {
|
||||
mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp);
|
||||
}
|
||||
} else {
|
||||
mpz_ptr gmpnum_base;
|
||||
FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base, 1);
|
||||
INIT_GMP_RETVAL(gmpnum_result);
|
||||
mpz_pow_ui(gmpnum_result, gmpnum_base, exp);
|
||||
if (exp >= INT_MAX) {
|
||||
mpz_t exp_num, mod;
|
||||
mpz_init(exp_num);
|
||||
mpz_init(mod);
|
||||
mpz_set_si(exp_num, exp);
|
||||
mpz_set_ui(mod, UINT_MAX);
|
||||
mpz_powm(gmpnum_result, gmpnum_base, exp_num, mod);
|
||||
mpz_clear(mod);
|
||||
mpz_clear(exp_num);
|
||||
} else {
|
||||
mpz_pow_ui(gmpnum_result, gmpnum_base, exp);
|
||||
}
|
||||
FREE_GMP_TEMP(temp_base);
|
||||
}
|
||||
}
|
||||
|
||||
20
ext/gmp/tests/gmp_pow_fpe.phpt
Normal file
20
ext/gmp/tests/gmp_pow_fpe.phpt
Normal file
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
gmp_pow() floating point exception
|
||||
--EXTENSIONS--
|
||||
gmp
|
||||
--FILE--
|
||||
<?php
|
||||
$g = gmp_init(256);
|
||||
|
||||
var_dump(gmp_pow($g, PHP_INT_MAX));
|
||||
var_dump(gmp_pow(256, PHP_INT_MAX));
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(GMP)#2 (1) {
|
||||
["num"]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
object(GMP)#2 (1) {
|
||||
["num"]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
Reference in New Issue
Block a user