Skip to content

Commit 56ca2bb

Browse files
author
foobar
committed
- Fixed bug #26267 (gmp_random() leaks memory and does not produce random numbers)
# ..and mpz_random() is obsolete according to the GNU MP manual.
1 parent 55b83c3 commit 56ca2bb

File tree

3 files changed

+62
-23
lines changed

3 files changed

+62
-23
lines changed

ext/gmp/config.m4

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ dnl $Id$
33
dnl
44

55
PHP_ARG_WITH(gmp, for GNU MP support,
6-
[ --with-gmp Include GNU MP support])
6+
[ --with-gmp[=DIR] Include GNU MP support])
77

88
if test "$PHP_GMP" != "no"; then
99

@@ -14,6 +14,18 @@ if test "$PHP_GMP" != "no"; then
1414
if test -z "$GMP_DIR"; then
1515
AC_MSG_ERROR(Unable to locate gmp.h)
1616
fi
17+
18+
PHP_CHECK_LIBRARY(gmp, __gmp_randinit_lc_2exp_size,
19+
[],[
20+
PHP_CHECK_LIBRARY(gmp, gmp_randinit_lc_2exp_size,
21+
[],[
22+
AC_MSG_ERROR([GNU MP Library version 4.1.2 or greater required.])
23+
],[
24+
-L$GMP_DIR/lib
25+
])
26+
],[
27+
-L$GMP_DIR/lib
28+
])
1729

1830
PHP_ADD_LIBRARY_WITH_PATH(gmp, $GMP_DIR/lib, GMP_SHARED_LIBADD)
1931
PHP_ADD_INCLUDE($GMP_DIR/include)

ext/gmp/gmp.c

+43-5
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
#if HAVE_GMP
2929

3030
#include <gmp.h>
31-
/* If you declare any globals in php_gmp.h uncomment this:
32-
ZEND_DECLARE_MODULE_GLOBALS(gmp)
33-
*/
31+
32+
/* Needed for gmp_random() */
33+
#include "ext/standard/php_rand.h"
34+
#include "ext/standard/php_lcg.h"
35+
#include <gmp-mparam.h>
36+
#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x))
3437

3538
/* True global resources - no need for thread safety here */
3639
static int le_gmp;
@@ -90,13 +93,15 @@ zend_module_entry gmp_module_entry = {
9093
ZEND_MODULE_STARTUP_N(gmp),
9194
ZEND_MODULE_SHUTDOWN_N(gmp),
9295
NULL,
93-
NULL,
96+
ZEND_MODULE_DEACTIVATE_N(gmp),
9497
ZEND_MODULE_INFO_N(gmp),
9598
NO_VERSION_YET,
9699
STANDARD_MODULE_PROPERTIES
97100
};
98101
/* }}} */
99102

103+
ZEND_DECLARE_MODULE_GLOBALS(gmp)
104+
100105
#ifdef COMPILE_DL_GMP
101106
ZEND_GET_MODULE(gmp)
102107
# ifdef PHP_WIN32
@@ -136,10 +141,20 @@ static void gmp_efree(void *ptr, size_t size)
136141
}
137142
/* }}} */
138143

144+
/* {{{ php_gmp_init_globals
145+
*/
146+
static void php_gmp_init_globals(zend_gmp_globals *gmp_globals)
147+
{
148+
gmp_globals->rand_initialized = 0;
149+
}
150+
/* }}} */
151+
139152
/* {{{ ZEND_MINIT_FUNCTION
140153
*/
141154
ZEND_MODULE_STARTUP_D(gmp)
142155
{
156+
ZEND_INIT_MODULE_GLOBALS(gmp, php_gmp_init_globals, NULL);
157+
143158
le_gmp = zend_register_list_destructors_ex(_php_gmpnum_free, NULL, GMP_RESOURCE_NAME, module_number);
144159
REGISTER_LONG_CONSTANT("GMP_ROUND_ZERO", GMP_ROUND_ZERO, CONST_CS | CONST_PERSISTENT);
145160
REGISTER_LONG_CONSTANT("GMP_ROUND_PLUSINF", GMP_ROUND_PLUSINF, CONST_CS | CONST_PERSISTENT);
@@ -151,6 +166,19 @@ ZEND_MODULE_STARTUP_D(gmp)
151166
}
152167
/* }}} */
153168

169+
/* {{{ ZEND_RSHUTDOWN_FUNCTION
170+
*/
171+
ZEND_MODULE_DEACTIVATE_D(gmp)
172+
{
173+
if (GMPG(rand_initialized)) {
174+
gmp_randclear(GMPG(rand_state));
175+
GMPG(rand_initialized) = 0;
176+
}
177+
178+
return SUCCESS;
179+
}
180+
/* }}} */
181+
154182
/* {{{ ZEND_MSHUTDOWN_FUNCTION
155183
*/
156184
ZEND_MODULE_SHUTDOWN_D(gmp)
@@ -1042,7 +1070,17 @@ ZEND_FUNCTION(gmp_random)
10421070
}
10431071

10441072
INIT_GMP_NUM(gmpnum_result);
1045-
mpz_random(*gmpnum_result, limiter);
1073+
1074+
if (!GMPG(rand_initialized)) {
1075+
/* Initialize */
1076+
gmp_randinit_lc_2exp_size(GMPG(rand_state), 32L);
1077+
1078+
/* Seed */
1079+
gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED());
1080+
1081+
GMPG(rand_initialized) = 1;
1082+
}
1083+
mpz_urandomb(*gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * BITS_PER_MP_LIMB);
10461084

10471085
ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);
10481086
}

ext/gmp/php_gmp.h

+6-17
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
#ifndef PHP_GMP_H
2020
#define PHP_GMP_H
2121

22-
/* You should tweak config.m4 so this symbol (or some else suitable)
23-
gets defined.
24-
*/
2522
#if HAVE_GMP
2623

24+
#include <gmp.h>
25+
2726
extern zend_module_entry gmp_module_entry;
2827
#define phpext_gmp_ptr &gmp_module_entry
2928

@@ -35,6 +34,7 @@ extern zend_module_entry gmp_module_entry;
3534

3635
ZEND_MODULE_STARTUP_D(gmp);
3736
ZEND_MODULE_SHUTDOWN_D(gmp);
37+
ZEND_MODULE_DEACTIVATE_D(gmp);
3838
ZEND_MODULE_INFO_D(gmp);
3939

4040
ZEND_FUNCTION(gmp_init);
@@ -76,24 +76,13 @@ ZEND_FUNCTION(gmp_scan1);
7676
ZEND_FUNCTION(gmp_popcount);
7777
ZEND_FUNCTION(gmp_hamdist);
7878

79-
/*
80-
Declare any global variables you may need between the BEGIN
81-
and END macros here:
82-
8379
ZEND_BEGIN_MODULE_GLOBALS(gmp)
84-
int global_variable;
80+
zend_bool rand_initialized;
81+
gmp_randstate_t rand_state;
8582
ZEND_END_MODULE_GLOBALS(gmp)
86-
*/
87-
88-
/* In every function that needs to use variables in php_gmp_globals,
89-
do call GMPLS_FETCH(); after declaring other variables used by
90-
that function, and always refer to them as GMPG(variable).
91-
You are encouraged to rename these macros something shorter, see
92-
examples in any other php module directory.
93-
*/
9483

9584
#ifdef ZTS
96-
#define GMPG(v) TSRMG(gmp_globals_id, php_gmp_globals *, v)
85+
#define GMPG(v) TSRMG(gmp_globals_id, zend_gmp_globals *, v)
9786
#else
9887
#define GMPG(v) (gmp_globals.v)
9988
#endif

0 commit comments

Comments
 (0)