cpython: 45fc0c83ed42 (original) (raw)

Mercurial > cpython

changeset 103172:45fc0c83ed42

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. [#27776]

Victor Stinner victor.stinner@gmail.com
date Tue, 06 Sep 2016 16:33:52 -0700
parents bb8fe61d78a4
children afa5a16456ed
files Doc/library/os.rst Doc/whatsnew/3.6.rst Include/pylifecycle.h Lib/random.py Misc/NEWS Modules/_randommodule.c Modules/posixmodule.c Python/random.c
diffstat 8 files changed, 131 insertions(+), 60 deletions(-)[+] [-] Doc/library/os.rst 29 Doc/whatsnew/3.6.rst 12 Include/pylifecycle.h 3 Lib/random.py 9 Misc/NEWS 4 Modules/_randommodule.c 56 Modules/posixmodule.c 3 Python/random.c 75

line wrap: on

line diff

--- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3968,14 +3968,27 @@ Random numbers returned data should be unpredictable enough for cryptographic applications, though its exact quality depends on the OS implementation.

+

.. versionchanged:: 3.5.2 On Linux, if the getrandom() syscall blocks (the urandom entropy pool

--- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -70,6 +70,12 @@ Standard library improvements:

--- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -117,7 +117,8 @@ PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsi PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); /* Random */ -PyAPI_FUNC(int) _PyOS_URandom (void *buffer, Py_ssize_t size); +PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size); +PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size); #ifdef __cplusplus }

--- a/Lib/random.py +++ b/Lib/random.py @@ -105,15 +105,6 @@ class Random(_random.Random): """

- if version == 1 and isinstance(a, (str, bytes)): x = ord(a[0]) << 7 if a else 0 for c in a:

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -89,6 +89,10 @@ Core and Builtins Library ------- +- Issue #27776: The :func:os.urandom function does now block on Linux 3.17

--- a/Modules/_randommodule.c +++ b/Modules/randommodule.c @@ -165,7 +165,7 @@ init_genrand(RandomObject *self, uint32 /* 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 } mt[0] = 0x80000000U; / MSB is 1; assuring non-zero initial array */

} /* @@ -199,6 +197,37 @@ init_by_array(RandomObject *self, uint32

+static int +random_seed_urandom(RandomObject *self) +{

+

+} + +static void +random_seed_time_pid(RandomObject *self) +{

+

+

+

+

+} + static PyObject * random_seed(RandomObject *self, PyObject *args) { @@ -212,14 +241,17 @@ random_seed(RandomObject *self, PyObject if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg)) return NULL;

@@ -269,7 +301,11 @@ random_seed(RandomObject *self, PyObject } } #endif

+

+ Done: Py_XDECREF(n); PyMem_Free(key);

--- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11168,8 +11168,7 @@ os_urandom_impl(PyObject *module, Py_ssi if (bytes == NULL) return NULL;

--- a/Python/random.c +++ b/Python/random.c @@ -77,7 +77,7 @@ win32_urandom(unsigned char buffer, Py_ } / Issue #25003: Don't use getentropy() on Solaris (available since

#elif defined(HAVE_GETENTROPY) && !defined(sun) #define PY_GETENTROPY 1 @@ -121,24 +121,20 @@ py_getentropy(char buffer, Py_ssize_t s / Call getrandom() - Return 1 on success

static int -py_getrandom(void *buffer, Py_ssize_t size, int raise) +py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) {

-

#ifdef sun @@ -185,15 +182,12 @@ py_getrandom(void *buffer, Py_ssize_t si getrandom_works = 0; return 0; }

@@ -228,13 +222,13 @@ static struct { } urandom_cache = { -1 }; -/* Read 'size' random bytes from getrandom(). Fall back on reading from +/* Read 'size' random bytes from py_getrandom(). Fall back on reading from /dev/urandom if getrandom() is not available. Return 0 on success. Raise an exception (if raise is non-zero) and return -1 on error. */ static int -dev_urandom(char *buffer, Py_ssize_t size, int raise) +dev_urandom(char *buffer, Py_ssize_t size, int blocking, int raise) { int fd; Py_ssize_t n; @@ -245,7 +239,7 @@ dev_urandom(char *buffer, Py_ssize_t siz assert(size > 0); #ifdef PY_GETRANDOM

@@ -400,7 +394,7 @@ pyurandom(void *buffer, Py_ssize_t size, #elif defined(PY_GETENTROPY) return py_getentropy(buffer, size, raise); #else

#endif } @@ -408,11 +402,29 @@ pyurandom(void *buffer, Py_ssize_t size, number generator (RNG). It is suitable for most cryptographic purposes except long living private keys for asymmetric encryption.

+} + +/* Fill buffer with size pseudo-random bytes from the operating system random

} void @@ -456,8 +468,11 @@ void int res; /* _PyRandom_Init() is called very early in the Python initialization

+