cpython: 1fc32bf069ff (original) (raw)

Mercurial > cpython

changeset 95042:1fc32bf069ff

Issue #22181: On Linux, os.urandom() now uses the new getrandom() syscall if available, syscall introduced in the Linux kernel 3.17. It is more reliable and more secure, because it avoids the need of a file descriptor and waits until the kernel has enough entropy. [#22181]

Victor Stinner victor.stinner@gmail.com
date Wed, 18 Mar 2015 14:39:33 +0100
parents 304f8011df9f
children f7c129f63922
files Misc/NEWS Python/random.c
diffstat 2 files changed, 89 insertions(+), 6 deletions(-)[+] [-] Misc/NEWS 5 Python/random.c 90

line wrap: on

line diff

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -18,6 +18,11 @@ Core and Builtins Library ------- +- Issue #22181: On Linux, os.urandom() now uses the new getrandom() syscall if

--- a/Python/random.c +++ b/Python/random.c @@ -1,11 +1,17 @@ #include "Python.h" #ifdef MS_WINDOWS -#include <windows.h> +# include <windows.h> #else -#include <fcntl.h> -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif +# include <fcntl.h> +# ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +# endif +# ifdef HAVE_SYS_SYSCALL_H +# include <sys/syscall.h> +# if defined(linux) && defined(SYS_getrandom) +# define HAVE_GETRANDOM +# endif +# endif #endif #ifdef Py_DEBUG @@ -94,13 +100,65 @@ py_getentropy(unsigned char buffer, Py_ return 0; } -#else +#else / !HAVE_GETENTROPY */ + +#ifdef HAVE_GETRANDOM +static int +py_getrandom(void *buffer, Py_ssize_t size, int raise) +{

+

+

+

+

+

+} +#endif + static struct { int fd; dev_t st_dev; ino_t st_ino; } urandom_cache = { -1 }; + /* Read size bytes from /dev/urandom into buffer. Call Py_FatalError() on error. */ static void @@ -115,6 +173,13 @@ dev_urandom_noraise(unsigned char *buffe if (fd < 0) Py_FatalError("Failed to open /dev/urandom"); +#ifdef HAVE_GETRANDOM

+#endif + while (0 < size) { do { @@ -140,10 +205,23 @@ dev_urandom_python(char *buffer, Py_ssiz int fd; Py_ssize_t n; struct _Py_stat_struct st; +#ifdef HAVE_GETRANDOM

+#endif if (size <= 0) return 0; +#ifdef HAVE_GETRANDOM

+#endif + if (urandom_cache.fd >= 0) { /* Does the fd point to the same thing as before? (issue #21207) */ if (_Py_fstat(urandom_cache.fd, &st)