Skip to content

Commit 47b430b

Browse files
committed
ext/gmp: Fix crash in gmp_pow with excessively large exponent - shift_operator_helper
1 parent eaa5120 commit 47b430b

2 files changed

Lines changed: 30 additions & 7 deletions

File tree

ext/gmp/gmp.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,37 @@ static zend_result shift_operator_helper(gmp_binary_ui_op_t op, zval *return_val
365365
return FAILURE;
366366
} else {
367367
mpz_ptr gmpnum_op, gmpnum_result;
368-
368+
size_t bits;
369+
369370
if (!gmp_zend_parse_arg_into_mpz_ex(op1, &gmpnum_op, 1, true)) {
370371
goto typeof_op_failure;
371372
}
372373

374+
bits = mpz_sizeinbase(gmpnum_op, 2);
375+
if (bits == 0) {
376+
bits = 1;
377+
}
378+
379+
if (opcode == ZEND_POW) {
380+
if ((size_t) shift > (SIZE_MAX - 5) / bits) {
381+
zend_value_error(
382+
"exponent results in a value that exceeds the supported size"
383+
);
384+
return FAILURE;
385+
}
386+
}
387+
388+
if (opcode == ZEND_SL) {
389+
size_t max_shift = ((size_t)INT_MAX * GMP_NUMB_BITS);
390+
391+
if ((size_t) shift > max_shift) {
392+
zend_value_error(
393+
"shift count results in a value that exceeds the supported size"
394+
);
395+
return FAILURE;
396+
}
397+
}
398+
373399
INIT_GMP_RETVAL(gmpnum_result);
374400
op(gmpnum_result, gmpnum_op, (gmp_ulong) shift);
375401
return SUCCESS;

ext/gmp/tests/gmp_overflow_llp64.phpt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,7 @@ try {
4949
echo "Done\n";
5050
?>
5151
--EXPECTF--
52-
gmp_pow(): Argument #2 ($exponent) must be between 0 and %d
53-
gmp_binomial(): Argument #2 ($k) must be between 0 and %d
54-
gmp_root(): Argument #2 ($nth) must be between 1 and %d
55-
gmp_rootrem(): Argument #2 ($nth) must be between 1 and %d
56-
Shift must be between 0 and %d
57-
Exponent must be between 0 and %d
52+
gmp_pow(): Argument #2 ($exponent) results in a value that exceeds the supported size
53+
shift count results in a value that exceeds the supported size
54+
exponent results in a value that exceeds the supported size
5855
Done

0 commit comments

Comments
 (0)