From: foobar Date: Wed, 19 Nov 2003 04:44:24 +0000 (+0000) Subject: MFH: - Fixed bug #26267 (gmp_random() leaks memory and does not produce random numbers) X-Git-Tag: php-4.3.5RC1~190 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=02ca709afd1cf7b31071431c52c86116b3af5300;p=php MFH: - Fixed bug #26267 (gmp_random() leaks memory and does not produce random numbers) --- diff --git a/NEWS b/NEWS index a98f841989..9f99f4d3a2 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ PHP 4 NEWS ?? ??? 2003, Version 4.3.5 - Fixed header handler in NSAPI SAPI module (header->replace was ignored, send_default_content_type now sends value from php.ini). (Uwe Schindler) +- Fixed bug #26267 (gmp_random() leaks memory and does not produce random + numbers). (Jani) - Fixed bug #26253 (ext/tokenizer: build as shared extension fails). (Jani) - Fixed bug #26235 (yp_first/yp_next do not specify correct key length). (Ilia) - Fixed bug #26216 ("getimagesize(): stream does not support seeking" when diff --git a/ext/gmp/config.m4 b/ext/gmp/config.m4 index 39e1bb24f9..aeb7edbd55 100644 --- a/ext/gmp/config.m4 +++ b/ext/gmp/config.m4 @@ -3,7 +3,7 @@ dnl $Id$ dnl PHP_ARG_WITH(gmp, for GNU MP support, -[ --with-gmp Include GNU MP support]) +[ --with-gmp[=DIR] Include GNU MP support]) if test "$PHP_GMP" != "no"; then @@ -14,6 +14,18 @@ if test "$PHP_GMP" != "no"; then if test -z "$GMP_DIR"; then AC_MSG_ERROR(Unable to locate gmp.h) fi + + PHP_CHECK_LIBRARY(gmp, __gmp_randinit_lc_2exp_size, + [],[ + PHP_CHECK_LIBRARY(gmp, gmp_randinit_lc_2exp_size, + [],[ + AC_MSG_ERROR([GNU MP Library version 4.1.2 or greater required.]) + ],[ + -L$GMP_DIR/lib + ]) + ],[ + -L$GMP_DIR/lib + ]) PHP_ADD_LIBRARY_WITH_PATH(gmp, $GMP_DIR/lib, GMP_SHARED_LIBADD) PHP_ADD_INCLUDE($GMP_DIR/include) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 717ed221df..ce5fa0af88 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -28,9 +28,12 @@ #if HAVE_GMP #include -/* If you declare any globals in php_gmp.h uncomment this: -ZEND_DECLARE_MODULE_GLOBALS(gmp) -*/ + +/* Needed for gmp_random() */ +#include "ext/standard/php_rand.h" +#include "ext/standard/php_lcg.h" +#include +#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) /* True global resources - no need for thread safety here */ static int le_gmp; @@ -92,13 +95,15 @@ zend_module_entry gmp_module_entry = { ZEND_MODULE_STARTUP_N(gmp), ZEND_MODULE_SHUTDOWN_N(gmp), NULL, - NULL, + ZEND_MODULE_DEACTIVATE_N(gmp), ZEND_MODULE_INFO_N(gmp), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES }; /* }}} */ +ZEND_DECLARE_MODULE_GLOBALS(gmp) + #ifdef COMPILE_DL_GMP ZEND_GET_MODULE(gmp) #endif @@ -135,10 +140,20 @@ static void gmp_efree(void *ptr, size_t size) } /* }}} */ +/* {{{ php_gmp_init_globals + */ +static void php_gmp_init_globals(zend_gmp_globals *gmp_globals) +{ + gmp_globals->rand_initialized = 0; +} +/* }}} */ + /* {{{ ZEND_MINIT_FUNCTION */ ZEND_MODULE_STARTUP_D(gmp) { + ZEND_INIT_MODULE_GLOBALS(gmp, php_gmp_init_globals, NULL); + le_gmp = zend_register_list_destructors_ex(_php_gmpnum_free, NULL, GMP_RESOURCE_NAME, module_number); REGISTER_LONG_CONSTANT("GMP_ROUND_ZERO", GMP_ROUND_ZERO, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("GMP_ROUND_PLUSINF", GMP_ROUND_PLUSINF, CONST_CS | CONST_PERSISTENT); @@ -150,6 +165,19 @@ ZEND_MODULE_STARTUP_D(gmp) } /* }}} */ +/* {{{ ZEND_RSHUTDOWN_FUNCTION + */ +ZEND_MODULE_DEACTIVATE_D(gmp) +{ + if (GMPG(rand_initialized)) { + gmp_randclear(GMPG(rand_state)); + GMPG(rand_initialized) = 0; + } + + return SUCCESS; +} +/* }}} */ + /* {{{ ZEND_MSHUTDOWN_FUNCTION */ ZEND_MODULE_SHUTDOWN_D(gmp) @@ -1041,7 +1069,17 @@ ZEND_FUNCTION(gmp_random) } INIT_GMP_NUM(gmpnum_result); - mpz_random(*gmpnum_result, limiter); + + if (!GMPG(rand_initialized)) { + /* Initialize */ + gmp_randinit_lc_2exp_size(GMPG(rand_state), 32L); + + /* Seed */ + gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED()); + + GMPG(rand_initialized) = 1; + } + mpz_urandomb(*gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * BITS_PER_MP_LIMB); ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); } diff --git a/ext/gmp/php_gmp.h b/ext/gmp/php_gmp.h index c6fdb3b6e1..8260e6a379 100644 --- a/ext/gmp/php_gmp.h +++ b/ext/gmp/php_gmp.h @@ -19,11 +19,10 @@ #ifndef PHP_GMP_H #define PHP_GMP_H -/* You should tweak config.m4 so this symbol (or some else suitable) - gets defined. -*/ #if HAVE_GMP +#include + extern zend_module_entry gmp_module_entry; #define phpext_gmp_ptr &gmp_module_entry @@ -35,6 +34,7 @@ extern zend_module_entry gmp_module_entry; ZEND_MODULE_STARTUP_D(gmp); ZEND_MODULE_SHUTDOWN_D(gmp); +ZEND_MODULE_DEACTIVATE_D(gmp); ZEND_MODULE_INFO_D(gmp); ZEND_FUNCTION(gmp_init); @@ -76,24 +76,13 @@ ZEND_FUNCTION(gmp_scan1); ZEND_FUNCTION(gmp_popcount); ZEND_FUNCTION(gmp_hamdist); -/* - Declare any global variables you may need between the BEGIN - and END macros here: - ZEND_BEGIN_MODULE_GLOBALS(gmp) - int global_variable; + zend_bool rand_initialized; + gmp_randstate_t rand_state; ZEND_END_MODULE_GLOBALS(gmp) -*/ - -/* In every function that needs to use variables in php_gmp_globals, - do call GMPLS_FETCH(); after declaring other variables used by - that function, and always refer to them as GMPG(variable). - You are encouraged to rename these macros something shorter, see - examples in any other php module directory. -*/ #ifdef ZTS -#define GMPG(v) TSRMG(gmp_globals_id, php_gmp_globals *, v) +#define GMPG(v) TSRMG(gmp_globals_id, zend_gmp_globals *, v) #else #define GMPG(v) (gmp_globals.v) #endif