From d541e7ad34b152da0aa475e55a21edbc477091ff Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 6 Sep 2016 13:24:00 -0700 Subject: replace Python aliases for standard integer types with the standard integer types (#17884) --- Modules/_randommodule.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) (limited to 'Modules/_randommodule.c') diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index fd6b230e85..63a060c1ea 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -69,10 +69,6 @@ #include "Python.h" #include /* for seeding to current time */ -#ifndef PY_UINT32_T -# error "Failed to find an exact-width 32-bit integer type" -#endif - /* Period parameters -- These are all magic. Don't change. */ #define N 624 #define M 397 @@ -83,7 +79,7 @@ typedef struct { PyObject_HEAD int index; - PY_UINT32_T state[N]; + uint32_t state[N]; } RandomObject; static PyTypeObject Random_Type; @@ -95,13 +91,13 @@ static PyTypeObject Random_Type; /* generates a random number on [0,0xffffffff]-interval */ -static PY_UINT32_T +static uint32_t genrand_int32(RandomObject *self) { - PY_UINT32_T y; - static const PY_UINT32_T mag01[2] = {0x0U, MATRIX_A}; + uint32_t y; + static const uint32_t mag01[2] = {0x0U, MATRIX_A}; /* mag01[x] = x * MATRIX_A for x=0,1 */ - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; if (self->index >= N) { /* generate N words at one time */ @@ -141,16 +137,16 @@ genrand_int32(RandomObject *self) static PyObject * random_random(RandomObject *self) { - PY_UINT32_T a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; + uint32_t a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); } /* initializes mt[N] with a seed */ static void -init_genrand(RandomObject *self, PY_UINT32_T s) +init_genrand(RandomObject *self, uint32_t s) { int mti; - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; mt[0]= s; @@ -170,10 +166,10 @@ init_genrand(RandomObject *self, PY_UINT32_T s) /* init_key is the array for initializing keys */ /* key_length is its length */ static PyObject * -init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) +init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) { size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; init_genrand(self, 19650218U); @@ -181,14 +177,14 @@ init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) k = (N>key_length ? N : key_length); for (; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) - + init_key[j] + (PY_UINT32_T)j; /* non linear */ + + init_key[j] + (uint32_t)j; /* non linear */ i++; j++; if (i>=N) { mt[0] = mt[N-1]; i=1; } if (j>=key_length) j=0; } for (k=N-1; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) - - (PY_UINT32_T)i; /* non linear */ + - (uint32_t)i; /* non linear */ i++; if (i>=N) { mt[0] = mt[N-1]; i=1; } } @@ -208,7 +204,7 @@ random_seed(RandomObject *self, PyObject *args) { PyObject *result = NULL; /* guilty until proved innocent */ PyObject *n = NULL; - PY_UINT32_T *key = NULL; + uint32_t *key = NULL; size_t bits, keyused; int res; PyObject *arg = NULL; @@ -220,7 +216,7 @@ random_seed(RandomObject *self, PyObject *args) time_t now; time(&now); - init_genrand(self, (PY_UINT32_T)now); + init_genrand(self, (uint32_t)now); Py_INCREF(Py_None); return Py_None; } @@ -248,7 +244,7 @@ random_seed(RandomObject *self, PyObject *args) keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; /* Convert seed to byte sequence. */ - key = (PY_UINT32_T *)PyMem_Malloc((size_t)4 * keyused); + key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused); if (key == NULL) { PyErr_NoMemory(); goto Done; @@ -267,7 +263,7 @@ random_seed(RandomObject *self, PyObject *args) size_t i, j; /* Reverse an array. */ for (i = 0, j = keyused - 1; i < j; i++, j--) { - PY_UINT32_T tmp = key[i]; + uint32_t tmp = key[i]; key[i] = key[j]; key[j] = tmp; } @@ -329,7 +325,7 @@ random_setstate(RandomObject *self, PyObject *state) element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); if (element == (unsigned long)-1 && PyErr_Occurred()) return NULL; - self->state[i] = (PY_UINT32_T)element; + self->state[i] = (uint32_t)element; } index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); @@ -349,8 +345,8 @@ static PyObject * random_getrandbits(RandomObject *self, PyObject *args) { int k, i, words; - PY_UINT32_T r; - PY_UINT32_T *wordarray; + uint32_t r; + uint32_t *wordarray; PyObject *result; if (!PyArg_ParseTuple(args, "i:getrandbits", &k)) @@ -366,7 +362,7 @@ random_getrandbits(RandomObject *self, PyObject *args) return PyLong_FromUnsignedLong(genrand_int32(self) >> (32 - k)); words = (k - 1) / 32 + 1; - wordarray = (PY_UINT32_T *)PyMem_Malloc(words * 4); + wordarray = (uint32_t *)PyMem_Malloc(words * 4); if (wordarray == NULL) { PyErr_NoMemory(); return NULL; -- cgit v1.2.1 From 87da9f01c3bc74aebedc52a91aa908ddae83a579 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 6 Sep 2016 16:33:52 -0700 Subject: os.urandom() now blocks on Linux Issue #27776: The os.urandom() function does now block on Linux 3.17 and newer until the system urandom entropy pool is initialized to increase the security. This change is part of the PEP 524. --- Modules/_randommodule.c | 56 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) (limited to 'Modules/_randommodule.c') diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 63a060c1ea..1cf57aea18 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -165,7 +165,7 @@ init_genrand(RandomObject *self, uint32_t s) /* initialize by an array with array-length */ /* init_key is the array for initializing keys */ /* key_length is its length */ -static PyObject * +static void init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) { size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ @@ -190,8 +190,6 @@ init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) } mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ - Py_INCREF(Py_None); - return Py_None; } /* @@ -199,6 +197,37 @@ init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) * Twister download. */ +static int +random_seed_urandom(RandomObject *self) +{ + PY_UINT32_T key[N]; + + if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) { + return -1; + } + init_by_array(self, key, Py_ARRAY_LENGTH(key)); + return 0; +} + +static void +random_seed_time_pid(RandomObject *self) +{ + _PyTime_t now; + uint32_t key[5]; + + now = _PyTime_GetSystemClock(); + key[0] = (PY_UINT32_T)(now & 0xffffffffU); + key[1] = (PY_UINT32_T)(now >> 32); + + key[2] = (PY_UINT32_T)getpid(); + + now = _PyTime_GetMonotonicClock(); + key[3] = (PY_UINT32_T)(now & 0xffffffffU); + key[4] = (PY_UINT32_T)(now >> 32); + + init_by_array(self, key, Py_ARRAY_LENGTH(key)); +} + static PyObject * random_seed(RandomObject *self, PyObject *args) { @@ -212,14 +241,17 @@ random_seed(RandomObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg)) return NULL; - if (arg == NULL || arg == Py_None) { - time_t now; + if (arg == NULL || arg == Py_None) { + if (random_seed_urandom(self) >= 0) { + PyErr_Clear(); - time(&now); - init_genrand(self, (uint32_t)now); - Py_INCREF(Py_None); - return Py_None; + /* Reading system entropy failed, fall back on the worst entropy: + use the current time and process identifier. */ + random_seed_time_pid(self); + } + Py_RETURN_NONE; } + /* This algorithm relies on the number being unsigned. * So: if the arg is a PyLong, use its absolute value. * Otherwise use its hash value, cast to unsigned. @@ -269,7 +301,11 @@ random_seed(RandomObject *self, PyObject *args) } } #endif - result = init_by_array(self, key, keyused); + init_by_array(self, key, keyused); + + Py_INCREF(Py_None); + result = Py_None; + Done: Py_XDECREF(n); PyMem_Free(key); -- cgit v1.2.1 From 81fcd610f43d28afbf8dabd25a8e40570ca3d92d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 6 Sep 2016 17:03:03 -0700 Subject: Issue #27776: include process.h on Windows for getpid() --- Modules/_randommodule.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Modules/_randommodule.c') diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 1cf57aea18..63759d5562 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -68,6 +68,9 @@ #include "Python.h" #include /* for seeding to current time */ +#ifdef HAVE_PROCESS_H +# include /* needed for getpid() */ +#endif /* Period parameters -- These are all magic. Don't change. */ #define N 624 -- cgit v1.2.1 From 665a02ced10494464e83c734d38526867be0d9ce Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 28 Dec 2016 20:02:35 -0800 Subject: fix error check, so that Random.seed actually uses OS randomness (closes #29085) --- Modules/_randommodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_randommodule.c') diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 63759d5562..0d3282db8f 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -245,7 +245,7 @@ random_seed(RandomObject *self, PyObject *args) return NULL; if (arg == NULL || arg == Py_None) { - if (random_seed_urandom(self) >= 0) { + if (random_seed_urandom(self) < 0) { PyErr_Clear(); /* Reading system entropy failed, fall back on the worst entropy: -- cgit v1.2.1