From 63396682441b84fb226b856269eb05cf933de1c5 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 12 Oct 2024 07:14:56 +0100 Subject: [PATCH] ext/gmp: gmp_pow fix FPE with large values. even without sanitizers, it is reproducible but with the following ``` = 0) { INIT_GMP_RETVAL(gmpnum_result); - 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); + if ((log10(Z_LVAL_P(base_arg)) * exp) > (double)ULONG_MAX) { + zend_value_error("base and exponent overflow"); + RETURN_THROWS(); } + mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp); } else { mpz_ptr gmpnum_base; + unsigned long gmpnum; FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base, 1); INIT_GMP_RETVAL(gmpnum_result); - 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); + gmpnum = mpz_get_ui(gmpnum_base); + if ((log10(gmpnum) * exp) > (double)ULONG_MAX) { + FREE_GMP_TEMP(temp_base); + zend_value_error("base and exponent overflow"); + RETURN_THROWS(); } + mpz_pow_ui(gmpnum_result, gmpnum_base, exp); FREE_GMP_TEMP(temp_base); } }