From 42a4a97e591b5988909a94f8898d79eeca026bb1 Mon Sep 17 00:00:00 2001 From: arshidkv12 Date: Wed, 17 Jun 2026 11:33:58 +0530 Subject: [PATCH 1/3] ext/gmp: Fix crash in gmp_pow with excessively large exponent --- ext/gmp/gmp.c | 5 +++-- ext/gmp/tests/gh22351.phpt | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 ext/gmp/tests/gh22351.phpt diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index ef06d0fda30c..9e356c85f240 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -48,6 +48,7 @@ #define GMP_LITTLE_ENDIAN (1 << 2) #define GMP_BIG_ENDIAN (1 << 3) #define GMP_NATIVE_ENDIAN (1 << 4) +#define GMP_POW_MAX_EXP 1000000L #include "gmp_arginfo.h" @@ -1131,8 +1132,8 @@ ZEND_FUNCTION(gmp_pow) Z_PARAM_LONG(exp) ZEND_PARSE_PARAMETERS_END(); - if (exp < 0 || exp > ULONG_MAX) { - zend_argument_value_error(2, "must be between 0 and %lu", ULONG_MAX); + if (exp < 0 || exp > GMP_POW_MAX_EXP) { + zend_argument_value_error(2, "must be between 0 and %lu", GMP_POW_MAX_EXP); RETURN_THROWS(); } diff --git a/ext/gmp/tests/gh22351.phpt b/ext/gmp/tests/gh22351.phpt new file mode 100644 index 000000000000..5b1e345a1609 --- /dev/null +++ b/ext/gmp/tests/gh22351.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-22351: gmp_pow with PHP_INT_MAX should not crash +--EXTENSIONS-- +gmp +--FILE-- +getMessage() . PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECTF-- +Testing gmp_pow overflow safety +ValueError: gmp_pow(): Argument #2 ($exponent) must be between 0 and 1000000 +Done \ No newline at end of file From 2223bc6d491d230e1a4c1cdf8e5b617e27531f28 Mon Sep 17 00:00:00 2001 From: arshidkv12 Date: Wed, 17 Jun 2026 11:34:40 +0530 Subject: [PATCH 2/3] ext/gmp: Fix crash in gmp_pow with excessively large exponent --- ext/gmp/tests/gh22351.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/gmp/tests/gh22351.phpt b/ext/gmp/tests/gh22351.phpt index 5b1e345a1609..b1b8e08100ac 100644 --- a/ext/gmp/tests/gh22351.phpt +++ b/ext/gmp/tests/gh22351.phpt @@ -19,4 +19,4 @@ echo "Done\n"; --EXPECTF-- Testing gmp_pow overflow safety ValueError: gmp_pow(): Argument #2 ($exponent) must be between 0 and 1000000 -Done \ No newline at end of file +Done From 666fe1678dcf9dfef67af3e274fb660e4e956540 Mon Sep 17 00:00:00 2001 From: arshidkv12 Date: Thu, 18 Jun 2026 08:58:02 +0530 Subject: [PATCH 3/3] ext/gmp: Fix crash in gmp_pow with excessively large exponent --- ext/gmp/gmp.c | 12 ++++++++++-- ext/gmp/tests/gh22351.phpt | 2 +- ext/gmp/tests/gmp_pow.phpt | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 9e356c85f240..c9700f331bfb 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1126,14 +1126,22 @@ ZEND_FUNCTION(gmp_pow) mpz_ptr gmpnum_result; mpz_ptr gmpnum_base; zend_long exp; + size_t bits; ZEND_PARSE_PARAMETERS_START(2, 2) GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_base) Z_PARAM_LONG(exp) ZEND_PARSE_PARAMETERS_END(); - if (exp < 0 || exp > GMP_POW_MAX_EXP) { - zend_argument_value_error(2, "must be between 0 and %lu", GMP_POW_MAX_EXP); + if (exp < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + + bits = mpz_sizeinbase(gmpnum_base, 2); + + if (exp < 0 || exp > (SIZE_MAX - 5) / bits) { + zend_argument_value_error(2, "results in a value that exceeds the supported size"); RETURN_THROWS(); } diff --git a/ext/gmp/tests/gh22351.phpt b/ext/gmp/tests/gh22351.phpt index b1b8e08100ac..d5aa0cec8fa9 100644 --- a/ext/gmp/tests/gh22351.phpt +++ b/ext/gmp/tests/gh22351.phpt @@ -18,5 +18,5 @@ echo "Done\n"; ?> --EXPECTF-- Testing gmp_pow overflow safety -ValueError: gmp_pow(): Argument #2 ($exponent) must be between 0 and 1000000 +ValueError: gmp_pow(): Argument #2 ($exponent) results in a value that exceeds the supported size Done diff --git a/ext/gmp/tests/gmp_pow.phpt b/ext/gmp/tests/gmp_pow.phpt index 36d0d16d8ccc..6a61cf43a617 100644 --- a/ext/gmp/tests/gmp_pow.phpt +++ b/ext/gmp/tests/gmp_pow.phpt @@ -49,11 +49,11 @@ string(4) "1024" string(5) "-2048" string(4) "1024" string(1) "1" -gmp_pow(): Argument #2 ($exponent) must be between 0 and %d +gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 string(4) "1024" string(14) "10240000000000" string(17) "97656250000000000" -gmp_pow(): Argument #2 ($exponent) must be between 0 and %d +gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 string(14) "10240000000000" string(14) "10240000000000" gmp_pow(): Argument #2 ($exponent) must be of type int, array given