diff options
| author | Victor Stinner <victor.stinner@gmail.com> | 2016-09-20 22:49:52 +0200 | 
|---|---|---|
| committer | Victor Stinner <victor.stinner@gmail.com> | 2016-09-20 22:49:52 +0200 | 
| commit | 75024c6589539f72af69ce61cd6493b193989c2d (patch) | |
| tree | 462b1f0020008ed484efc83a5b0eb3cd74fc016e /Python/random.c | |
| parent | 7582bcaa8faf348fb6894617846ba41b5782ea06 (diff) | |
| parent | 6d8bc46cc0ebe75d86d00a6ee7c452beea761c42 (diff) | |
| download | cpython-git-75024c6589539f72af69ce61cd6493b193989c2d.tar.gz | |
(Merge 3.5) Catch EPERM error in py_getrandom()
Issue #27955: Fallback on reading /dev/urandom device when the getrandom()
syscall fails with EPERM, for example when blocked by SECCOMP.
Diffstat (limited to 'Python/random.c')
| -rw-r--r-- | Python/random.c | 19 | 
1 files changed, 11 insertions, 8 deletions
diff --git a/Python/random.c b/Python/random.c index ea506eeeb2..6f9f711074 100644 --- a/Python/random.c +++ b/Python/random.c @@ -121,9 +121,9 @@ py_getentropy(char *buffer, Py_ssize_t size, int raise)  /* Call getrandom()     - Return 1 on success -   - Return 0 if getrandom() syscall is not available (fails with ENOSYS) -     or if getrandom(GRND_NONBLOCK) fails with EAGAIN (blocking=0 and system -     urandom not initialized yet) and raise=0. +   - Return 0 if getrandom() syscall is not available (failed with ENOSYS or +     EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom +     not initialized yet) and raise=0.     - Raise an exception (if raise is non-zero) and return -1 on error:       getrandom() failed with EINTR and the Python signal handler raised an       exception, or getrandom() failed with a different error. */ @@ -131,8 +131,8 @@ static int  py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)  {      /* Is getrandom() supported by the running kernel? Set to 0 if getrandom() -       fails with ENOSYS. Need Linux kernel 3.17 or newer, or Solaris 11.3 -       or newer */ +       failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris +       11.3 or newer */      static int getrandom_works = 1;      int flags;      char *dest; @@ -178,7 +178,10 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise)  #endif          if (n < 0) { -            if (errno == ENOSYS) { +            /* ENOSYS: getrandom() syscall not supported by the kernel (but +             * maybe supported by the host which built Python). EPERM: +             * getrandom() syscall blocked by SECCOMP or something else. */ +            if (errno == ENOSYS || errno == EPERM) {                  getrandom_works = 0;                  return 0;              } @@ -246,8 +249,8 @@ dev_urandom(char *buffer, Py_ssize_t size, int blocking, int raise)      if (res == 1) {          return 0;      } -    /* getrandom() is not supported by the running kernel, fall back -       on reading /dev/urandom */ +    /* getrandom() failed with ENOSYS or EPERM, +       fall back on reading /dev/urandom */  #endif  | 
