components/python/python35/patches/27-getrandom.patch
changeset 4912 0b79e9575718
equal deleted inserted replaced
4911:6590570733a1 4912:0b79e9575718
       
     1 This patch comes from upstream: http://bugs.python.org/issue25003
       
     2 
       
     3 --- a/configure	Fri Sep 11 12:38:27 2015 +0200
       
     4 +++ b/configure	Fri Sep 11 13:06:42 2015 +0200
       
     5 @@ -16180,11 +16180,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_
       
     6      #include <sys/syscall.h>
       
     7  
       
     8      int main() {
       
     9 +        char buffer[1];
       
    10 +        const size_t buflen = sizeof(buffer);
       
    11          const int flags = 0;
       
    12 -        char buffer[1];
       
    13 -        int n;
       
    14          /* ignore the result, Python checks for ENOSYS at runtime */
       
    15 -        (void)syscall(SYS_getrandom, buffer, sizeof(buffer), flags);
       
    16 +        (void)syscall(SYS_getrandom, buffer, buflen, flags);
       
    17          return 0;
       
    18      }
       
    19  
       
    20 @@ -16206,6 +16206,43 @@ if test "$have_getrandom_syscall" = yes;
       
    21  
       
    22  fi
       
    23  
       
    24 +# check if the getrandom() function is available
       
    25 +# the test was written for the Solaris function of <sys/random.h>
       
    26 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the getrandom() function" >&5
       
    27 +$as_echo_n "checking for the getrandom() function... " >&6; }
       
    28 +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
       
    29 +/* end confdefs.h.  */
       
    30 +
       
    31 +
       
    32 +    #include <sys/random.h>
       
    33 +
       
    34 +    int main() {
       
    35 +        char buffer[1];
       
    36 +        const size_t buflen = sizeof(buffer);
       
    37 +        const int flags = 0;
       
    38 +        /* ignore the result, Python checks for ENOSYS at runtime */
       
    39 +        (void)getrandom(buffer, buflen, flags);
       
    40 +        return 0;
       
    41 +    }
       
    42 +
       
    43 +
       
    44 +_ACEOF
       
    45 +if ac_fn_c_try_link "$LINENO"; then :
       
    46 +  have_getrandom=yes
       
    47 +else
       
    48 +  have_getrandom=no
       
    49 +fi
       
    50 +rm -f core conftest.err conftest.$ac_objext \
       
    51 +    conftest$ac_exeext conftest.$ac_ext
       
    52 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_getrandom" >&5
       
    53 +$as_echo "$have_getrandom" >&6; }
       
    54 +
       
    55 +if test "$have_getrandom" = yes; then
       
    56 +
       
    57 +$as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h
       
    58 +
       
    59 +fi
       
    60 +
       
    61  # generate output files
       
    62  ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
       
    63  
       
    64 --- a/configure.ac	Fri Sep 11 12:38:27 2015 +0200
       
    65 +++ b/configure.ac	Fri Sep 11 13:06:42 2015 +0200
       
    66 @@ -5161,11 +5161,11 @@ AC_LINK_IFELSE(
       
    67      #include <sys/syscall.h>
       
    68  
       
    69      int main() {
       
    70 +        char buffer[1];
       
    71 +        const size_t buflen = sizeof(buffer);
       
    72          const int flags = 0;
       
    73 -        char buffer[1];
       
    74 -        int n;
       
    75          /* ignore the result, Python checks for ENOSYS at runtime */
       
    76 -        (void)syscall(SYS_getrandom, buffer, sizeof(buffer), flags);
       
    77 +        (void)syscall(SYS_getrandom, buffer, buflen, flags);
       
    78          return 0;
       
    79      }
       
    80    ]])
       
    81 @@ -5177,6 +5177,31 @@ if test "$have_getrandom_syscall" = yes;
       
    82                [Define to 1 if the Linux getrandom() syscall is available])
       
    83  fi
       
    84  
       
    85 +# check if the getrandom() function is available
       
    86 +# the test was written for the Solaris function of <sys/random.h>
       
    87 +AC_MSG_CHECKING(for the getrandom() function)
       
    88 +AC_LINK_IFELSE(
       
    89 +[
       
    90 +  AC_LANG_SOURCE([[
       
    91 +    #include <sys/random.h>
       
    92 +
       
    93 +    int main() {
       
    94 +        char buffer[1];
       
    95 +        const size_t buflen = sizeof(buffer);
       
    96 +        const int flags = 0;
       
    97 +        /* ignore the result, Python checks for ENOSYS at runtime */
       
    98 +        (void)getrandom(buffer, buflen, flags);
       
    99 +        return 0;
       
   100 +    }
       
   101 +  ]])
       
   102 +],[have_getrandom=yes],[have_getrandom=no])
       
   103 +AC_MSG_RESULT($have_getrandom)
       
   104 +
       
   105 +if test "$have_getrandom" = yes; then
       
   106 +    AC_DEFINE(HAVE_GETRANDOM, 1,
       
   107 +              [Define to 1 if the getrandom() function is available])
       
   108 +fi
       
   109 +
       
   110  # generate output files
       
   111  AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh)
       
   112  AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
       
   113 --- Python-3.5.0/Lib/test/test_os.py.~1~	2015-09-13 04:41:23.000000000 -0700
       
   114 +++ Python-3.5.0/Lib/test/test_os.py	2015-09-14 13:43:47.884863398 -0700
       
   115 @@ -1213,13 +1213,17 @@
       
   116          self.assertNotEqual(data1, data2)
       
   117  
       
   118  
       
   119 -HAVE_GETENTROPY = (sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
       
   120 -HAVE_GETRANDOM = (sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
       
   121 +USE_GETENTROPY = ((sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
       
   122 +                  and not sys.platform.startswith("sunos"))
       
   123 +HAVE_GETRANDOM = (sysconfig.get_config_var('HAVE_GETRANDOM') == 1)
       
   124 +HAVE_GETRANDOM_SYSCALL = (sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
       
   125  
       
   126 [email protected](HAVE_GETENTROPY,
       
   127 [email protected](USE_GETENTROPY,
       
   128                   "getentropy() does not use a file descriptor")
       
   129  @unittest.skipIf(HAVE_GETRANDOM,
       
   130                   "getrandom() does not use a file descriptor")
       
   131 [email protected](HAVE_GETRANDOM_SYSCALL,
       
   132 +                 "getrandom() does not use a file descriptor")
       
   133  class URandomFDTests(unittest.TestCase):
       
   134      @unittest.skipUnless(resource, "test requires the resource module")
       
   135      def test_urandom_failure(self):
       
   136 --- Python-3.5.0/Python/random.c.~2~	2015-09-14 14:11:43.377801246 -0700
       
   137 +++ Python-3.5.0/Python/random.c	2015-09-14 14:19:35.124606276 -0700
       
   138 @@ -6,11 +6,20 @@
       
   139  #  ifdef HAVE_SYS_STAT_H
       
   140  #    include <sys/stat.h>
       
   141  #  endif
       
   142 -#  ifdef HAVE_GETRANDOM_SYSCALL
       
   143 +#  ifdef HAVE_GETRANDOM
       
   144 +#    include <sys/random.h>
       
   145 +#  elif defined(HAVE_GETRANDOM_SYSCALL)
       
   146  #    include <sys/syscall.h>
       
   147  #  endif
       
   148  #endif
       
   149  
       
   150 +/* Solaris 11.3 provides getrandom() and getentropy(). getentropy() cannot be
       
   151 +   used for os.urandom() because it is blocking, it. Use
       
   152 +   getrandom(GRND_NONBLOCK) instead, it is non-blocking. */
       
   153 +#if defined(HAVE_GETENTROPY) && !defined(sun)
       
   154 +#  define USE_GETENTROPY
       
   155 +#endif
       
   156 +
       
   157  #ifdef Py_DEBUG
       
   158  int _Py_HashSecret_Initialized = 0;
       
   159  #else
       
   160 @@ -70,7 +79,7 @@
       
   161      return 0;
       
   162  }
       
   163  
       
   164 -#elif HAVE_GETENTROPY
       
   165 +#elif defined(USE_GETENTROPY)
       
   166  /* Fill buffer with size pseudo-random bytes generated by getentropy().
       
   167     Return 0 on success, or raise an exception and return -1 on error.
       
   168  
       
   169 @@ -105,16 +114,19 @@
       
   170      return 0;
       
   171  }
       
   172  
       
   173 -#else   /* !HAVE_GETENTROPY */
       
   174 +#else   /* !USE_GETENTROPY */
       
   175 +
       
   176 +#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
       
   177 +#define PY_GETRANDOM
       
   178  
       
   179 -#ifdef HAVE_GETRANDOM_SYSCALL
       
   180  static int
       
   181  py_getrandom(void *buffer, Py_ssize_t size, int raise)
       
   182  {
       
   183 -    /* is getrandom() supported by the running kernel?
       
   184 -     * need Linux kernel 3.17 or later */
       
   185 +    /* Is getrandom() supported by the running kernel?
       
   186 +     * Need Linux kernel 3.17 or newer, or Solaris 11.3 or newer */
       
   187      static int getrandom_works = 1;
       
   188 -    /* Use /dev/urandom, block if the kernel has no entropy */
       
   189 +    /* Use non-blocking /dev/urandom device. On Linux at boot, the getrandom()
       
   190 +     * syscall blocks until /dev/urandom is initialized with enough entropy. */
       
   191      const int flags = 0;
       
   192      int n;
       
   193  
       
   194 @@ -124,7 +136,18 @@
       
   195      while (0 < size) {
       
   196          errno = 0;
       
   197  
       
   198 -        /* Use syscall() because the libc doesn't expose getrandom() yet, see:
       
   199 +#ifdef HAVE_GETRANDOM
       
   200 +        if (raise) {
       
   201 +            Py_BEGIN_ALLOW_THREADS
       
   202 +            n = getrandom(buffer, size, flags);
       
   203 +            Py_END_ALLOW_THREADS
       
   204 +        }
       
   205 +        else {
       
   206 +            n = getrandom(buffer, size, flags);
       
   207 +        }
       
   208 +#else
       
   209 +        /* On Linux, use the syscall() function because the GNU libc doesn't
       
   210 +         * expose the Linux getrandom() syscall yet. See:
       
   211           * https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
       
   212          if (raise) {
       
   213              Py_BEGIN_ALLOW_THREADS
       
   214 @@ -134,6 +157,7 @@
       
   215          else {
       
   216              n = syscall(SYS_getrandom, buffer, size, flags);
       
   217          }
       
   218 +#endif
       
   219  
       
   220          if (n < 0) {
       
   221              if (errno == ENOSYS || errno == EINVAL) {
       
   222 @@ -182,7 +206,7 @@
       
   223  
       
   224      assert (0 < size);
       
   225  
       
   226 -#ifdef HAVE_GETRANDOM_SYSCALL
       
   227 +#ifdef PY_GETRANDOM
       
   228      if (py_getrandom(buffer, size, 0) == 1)
       
   229          return;
       
   230      /* getrandom() is not supported by the running kernel, fall back
       
   231 @@ -218,14 +242,14 @@
       
   232      int fd;
       
   233      Py_ssize_t n;
       
   234      struct _Py_stat_struct st;
       
   235 -#ifdef HAVE_GETRANDOM_SYSCALL
       
   236 +#ifdef PY_GETRANDOM
       
   237      int res;
       
   238  #endif
       
   239  
       
   240      if (size <= 0)
       
   241          return 0;
       
   242  
       
   243 -#ifdef HAVE_GETRANDOM_SYSCALL
       
   244 +#ifdef PY_GETRANDOM
       
   245      res = py_getrandom(buffer, size, 1);
       
   246      if (res < 0)
       
   247          return -1;
       
   248 @@ -304,7 +328,7 @@
       
   249      }
       
   250  }
       
   251  
       
   252 -#endif /* HAVE_GETENTROPY */
       
   253 +#endif
       
   254  
       
   255  /* Fill buffer with pseudo-random bytes generated by a linear congruent
       
   256     generator (LCG):
       
   257 @@ -345,7 +369,7 @@
       
   258  
       
   259  #ifdef MS_WINDOWS
       
   260      return win32_urandom((unsigned char *)buffer, size, 1);
       
   261 -#elif HAVE_GETENTROPY
       
   262 +#elif defined(USE_GETENTROPY)
       
   263      return py_getentropy(buffer, size, 0);
       
   264  #else
       
   265      return dev_urandom_python((char*)buffer, size);
       
   266 @@ -392,7 +416,7 @@
       
   267      else {
       
   268  #ifdef MS_WINDOWS
       
   269          (void)win32_urandom(secret, secret_size, 0);
       
   270 -#elif HAVE_GETENTROPY
       
   271 +#elif defined(USE_GETENTROPY)
       
   272          (void)py_getentropy(secret, secret_size, 1);
       
   273  #else
       
   274          dev_urandom_noraise(secret, secret_size);
       
   275 @@ -408,7 +432,7 @@
       
   276          CryptReleaseContext(hCryptProv, 0);
       
   277          hCryptProv = 0;
       
   278      }
       
   279 -#elif HAVE_GETENTROPY
       
   280 +#elif defined(USE_GETENTROPY)
       
   281      /* nothing to clean */
       
   282  #else
       
   283      dev_urandom_close();
       
   284 --- a/pyconfig.h.in	Fri Sep 11 12:38:27 2015 +0200
       
   285 +++ b/pyconfig.h.in	Fri Sep 11 13:06:42 2015 +0200
       
   286 @@ -395,6 +395,9 @@
       
   287  /* Define to 1 if you have the `getpwent' function. */
       
   288  #undef HAVE_GETPWENT
       
   289  
       
   290 +/* Define to 1 if the getrandom() function is available */
       
   291 +#undef HAVE_GETRANDOM
       
   292 +
       
   293  /* Define to 1 if the Linux getrandom() syscall is available */
       
   294  #undef HAVE_GETRANDOM_SYSCALL
       
   295