Skip to content

Commit 6339668

Browse files
committed
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 php#2 0x7faf6db9386c in __gmp_exception (/lib/x86_64-linux-gnu/libgmp.so.10+0xd86c) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38) php#3 0x7faf6db938d3 in __gmp_overflow_in_mpz (/lib/x86_64-linux-gnu/libgmp.so.10+0xd8d3) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38) php#4 0x7faf6dbac95c in __gmpz_realloc (/lib/x86_64-linux-gnu/libgmp.so.10+0x2695c) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38) php#5 0x7faf6dba9038 in __gmpz_n_pow_ui (/lib/x86_64-linux-gnu/libgmp.so.10+0x23038) (BuildId: 1af68a49fe041a5bb48a2915c3d47541f713bb38) php#6 0x5565ae1ccd9f in zif_gmp_pow /home/dcarlier/Contribs/php-src/ext/gmp/gmp.c:1286 php#7 0x5565aee96ea9 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:1312 php#8 0x5565af144320 in execute_ex /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:56075 php#9 0x5565af160f07 in zend_execute /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:60439 php#10 0x5565aed6fafe in zend_execute_scripts /home/dcarlier/Contribs/php-src/Zend/zend.c:1842 php#11 0x5565aeae70a8 in php_execute_script /home/dcarlier/Contribs/php-src/main/main.c:2578 php#12 0x5565af532f4e in do_cli /home/dcarlier/Contribs/php-src/sapi/cli/php_cli.c:964 php#13 0x5565af535877 in main /home/dcarlier/Contribs/php-src/sapi/cli/php_cli.c:1334 php#14 0x7faf6c633d67 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 php#15 0x7faf6c633e24 in __libc_start_main_impl ../csu/libc-start.c:360 php#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 ```
1 parent 7fe168d commit 6339668

File tree

1 file changed

+11
-25
lines changed

1 file changed

+11
-25
lines changed

ext/gmp/gmp.c

+11-25
Original file line numberDiff line numberDiff line change
@@ -1284,37 +1284,23 @@ ZEND_FUNCTION(gmp_pow)
12841284

12851285
if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) {
12861286
INIT_GMP_RETVAL(gmpnum_result);
1287-
if (exp >= INT_MAX) {
1288-
mpz_t base_num, exp_num, mod;
1289-
mpz_init(base_num);
1290-
mpz_init(exp_num);
1291-
mpz_init(mod);
1292-
mpz_set_si(base_num, Z_LVAL_P(base_arg));
1293-
mpz_set_si(exp_num, exp);
1294-
mpz_set_ui(mod, UINT_MAX);
1295-
mpz_powm(gmpnum_result, base_num, exp_num, mod);
1296-
mpz_clear(mod);
1297-
mpz_clear(exp_num);
1298-
mpz_clear(base_num);
1299-
} else {
1300-
mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp);
1287+
if ((log10(Z_LVAL_P(base_arg)) * exp) > (double)ULONG_MAX) {
1288+
zend_value_error("base and exponent overflow");
1289+
RETURN_THROWS();
13011290
}
1291+
mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp);
13021292
} else {
13031293
mpz_ptr gmpnum_base;
1294+
unsigned long gmpnum;
13041295
FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base, 1);
13051296
INIT_GMP_RETVAL(gmpnum_result);
1306-
if (exp >= INT_MAX) {
1307-
mpz_t exp_num, mod;
1308-
mpz_init(exp_num);
1309-
mpz_init(mod);
1310-
mpz_set_si(exp_num, exp);
1311-
mpz_set_ui(mod, UINT_MAX);
1312-
mpz_powm(gmpnum_result, gmpnum_base, exp_num, mod);
1313-
mpz_clear(mod);
1314-
mpz_clear(exp_num);
1315-
} else {
1316-
mpz_pow_ui(gmpnum_result, gmpnum_base, exp);
1297+
gmpnum = mpz_get_ui(gmpnum_base);
1298+
if ((log10(gmpnum) * exp) > (double)ULONG_MAX) {
1299+
FREE_GMP_TEMP(temp_base);
1300+
zend_value_error("base and exponent overflow");
1301+
RETURN_THROWS();
13171302
}
1303+
mpz_pow_ui(gmpnum_result, gmpnum_base, exp);
13181304
FREE_GMP_TEMP(temp_base);
13191305
}
13201306
}

0 commit comments

Comments
 (0)