This patch comes from upstream: http://bugs.python.org/issue25003
--- a/configure Fri Sep 11 12:38:27 2015 +0200
+++ b/configure Fri Sep 11 13:06:42 2015 +0200
@@ -16180,11 +16180,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_
#include <sys/syscall.h>
int main() {
+ char buffer[1];
+ const size_t buflen = sizeof(buffer);
const int flags = 0;
- char buffer[1];
- int n;
/* ignore the result, Python checks for ENOSYS at runtime */
- (void)syscall(SYS_getrandom, buffer, sizeof(buffer), flags);
+ (void)syscall(SYS_getrandom, buffer, buflen, flags);
return 0;
}
@@ -16206,6 +16206,43 @@ if test "$have_getrandom_syscall" = yes;
fi
+# check if the getrandom() function is available
+# the test was written for the Solaris function of <sys/random.h>
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the getrandom() function" >&5
+$as_echo_n "checking for the getrandom() function... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+ #include <sys/random.h>
+
+ int main() {
+ char buffer[1];
+ const size_t buflen = sizeof(buffer);
+ const int flags = 0;
+ /* ignore the result, Python checks for ENOSYS at runtime */
+ (void)getrandom(buffer, buflen, flags);
+ return 0;
+ }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ have_getrandom=yes
+else
+ have_getrandom=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_getrandom" >&5
+$as_echo "$have_getrandom" >&6; }
+
+if test "$have_getrandom" = yes; then
+
+$as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h
+
+fi
+
# generate output files
ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
--- a/configure.ac Fri Sep 11 12:38:27 2015 +0200
+++ b/configure.ac Fri Sep 11 13:06:42 2015 +0200
@@ -5161,11 +5161,11 @@ AC_LINK_IFELSE(
#include <sys/syscall.h>
int main() {
+ char buffer[1];
+ const size_t buflen = sizeof(buffer);
const int flags = 0;
- char buffer[1];
- int n;
/* ignore the result, Python checks for ENOSYS at runtime */
- (void)syscall(SYS_getrandom, buffer, sizeof(buffer), flags);
+ (void)syscall(SYS_getrandom, buffer, buflen, flags);
return 0;
}
]])
@@ -5177,6 +5177,31 @@ if test "$have_getrandom_syscall" = yes;
[Define to 1 if the Linux getrandom() syscall is available])
fi
+# check if the getrandom() function is available
+# the test was written for the Solaris function of <sys/random.h>
+AC_MSG_CHECKING(for the getrandom() function)
+AC_LINK_IFELSE(
+[
+ AC_LANG_SOURCE([[
+ #include <sys/random.h>
+
+ int main() {
+ char buffer[1];
+ const size_t buflen = sizeof(buffer);
+ const int flags = 0;
+ /* ignore the result, Python checks for ENOSYS at runtime */
+ (void)getrandom(buffer, buflen, flags);
+ return 0;
+ }
+ ]])
+],[have_getrandom=yes],[have_getrandom=no])
+AC_MSG_RESULT($have_getrandom)
+
+if test "$have_getrandom" = yes; then
+ AC_DEFINE(HAVE_GETRANDOM, 1,
+ [Define to 1 if the getrandom() function is available])
+fi
+
# generate output files
AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh)
AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
--- Python-3.5.0/Lib/test/test_os.py.~1~ 2015-09-13 04:41:23.000000000 -0700
+++ Python-3.5.0/Lib/test/test_os.py 2015-09-14 13:43:47.884863398 -0700
@@ -1213,13 +1213,17 @@
self.assertNotEqual(data1, data2)
-HAVE_GETENTROPY = (sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
-HAVE_GETRANDOM = (sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
+USE_GETENTROPY = ((sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
+ and not sys.platform.startswith("sunos"))
+HAVE_GETRANDOM = (sysconfig.get_config_var('HAVE_GETRANDOM') == 1)
+HAVE_GETRANDOM_SYSCALL = (sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
[email protected](HAVE_GETENTROPY,
[email protected](USE_GETENTROPY,
"getentropy() does not use a file descriptor")
@unittest.skipIf(HAVE_GETRANDOM,
"getrandom() does not use a file descriptor")
[email protected](HAVE_GETRANDOM_SYSCALL,
+ "getrandom() does not use a file descriptor")
class URandomFDTests(unittest.TestCase):
@unittest.skipUnless(resource, "test requires the resource module")
def test_urandom_failure(self):
--- Python-3.5.0/Python/random.c.~2~ 2015-09-14 14:11:43.377801246 -0700
+++ Python-3.5.0/Python/random.c 2015-09-14 14:19:35.124606276 -0700
@@ -6,11 +6,20 @@
# ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
# endif
-# ifdef HAVE_GETRANDOM_SYSCALL
+# ifdef HAVE_GETRANDOM
+# include <sys/random.h>
+# elif defined(HAVE_GETRANDOM_SYSCALL)
# include <sys/syscall.h>
# endif
#endif
+/* Solaris 11.3 provides getrandom() and getentropy(). getentropy() cannot be
+ used for os.urandom() because it is blocking, it. Use
+ getrandom(GRND_NONBLOCK) instead, it is non-blocking. */
+#if defined(HAVE_GETENTROPY) && !defined(sun)
+# define USE_GETENTROPY
+#endif
+
#ifdef Py_DEBUG
int _Py_HashSecret_Initialized = 0;
#else
@@ -70,7 +79,7 @@
return 0;
}
-#elif HAVE_GETENTROPY
+#elif defined(USE_GETENTROPY)
/* Fill buffer with size pseudo-random bytes generated by getentropy().
Return 0 on success, or raise an exception and return -1 on error.
@@ -105,16 +114,19 @@
return 0;
}
-#else /* !HAVE_GETENTROPY */
+#else /* !USE_GETENTROPY */
+
+#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
+#define PY_GETRANDOM
-#ifdef HAVE_GETRANDOM_SYSCALL
static int
py_getrandom(void *buffer, Py_ssize_t size, int raise)
{
- /* is getrandom() supported by the running kernel?
- * need Linux kernel 3.17 or later */
+ /* Is getrandom() supported by the running kernel?
+ * Need Linux kernel 3.17 or newer, or Solaris 11.3 or newer */
static int getrandom_works = 1;
- /* Use /dev/urandom, block if the kernel has no entropy */
+ /* Use non-blocking /dev/urandom device. On Linux at boot, the getrandom()
+ * syscall blocks until /dev/urandom is initialized with enough entropy. */
const int flags = 0;
int n;
@@ -124,7 +136,18 @@
while (0 < size) {
errno = 0;
- /* Use syscall() because the libc doesn't expose getrandom() yet, see:
+#ifdef HAVE_GETRANDOM
+ if (raise) {
+ Py_BEGIN_ALLOW_THREADS
+ n = getrandom(buffer, size, flags);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ n = getrandom(buffer, size, flags);
+ }
+#else
+ /* On Linux, use the syscall() function because the GNU libc doesn't
+ * expose the Linux getrandom() syscall yet. See:
* https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
if (raise) {
Py_BEGIN_ALLOW_THREADS
@@ -134,6 +157,7 @@
else {
n = syscall(SYS_getrandom, buffer, size, flags);
}
+#endif
if (n < 0) {
if (errno == ENOSYS || errno == EINVAL) {
@@ -182,7 +206,7 @@
assert (0 < size);
-#ifdef HAVE_GETRANDOM_SYSCALL
+#ifdef PY_GETRANDOM
if (py_getrandom(buffer, size, 0) == 1)
return;
/* getrandom() is not supported by the running kernel, fall back
@@ -218,14 +242,14 @@
int fd;
Py_ssize_t n;
struct _Py_stat_struct st;
-#ifdef HAVE_GETRANDOM_SYSCALL
+#ifdef PY_GETRANDOM
int res;
#endif
if (size <= 0)
return 0;
-#ifdef HAVE_GETRANDOM_SYSCALL
+#ifdef PY_GETRANDOM
res = py_getrandom(buffer, size, 1);
if (res < 0)
return -1;
@@ -304,7 +328,7 @@
}
}
-#endif /* HAVE_GETENTROPY */
+#endif
/* Fill buffer with pseudo-random bytes generated by a linear congruent
generator (LCG):
@@ -345,7 +369,7 @@
#ifdef MS_WINDOWS
return win32_urandom((unsigned char *)buffer, size, 1);
-#elif HAVE_GETENTROPY
+#elif defined(USE_GETENTROPY)
return py_getentropy(buffer, size, 0);
#else
return dev_urandom_python((char*)buffer, size);
@@ -392,7 +416,7 @@
else {
#ifdef MS_WINDOWS
(void)win32_urandom(secret, secret_size, 0);
-#elif HAVE_GETENTROPY
+#elif defined(USE_GETENTROPY)
(void)py_getentropy(secret, secret_size, 1);
#else
dev_urandom_noraise(secret, secret_size);
@@ -408,7 +432,7 @@
CryptReleaseContext(hCryptProv, 0);
hCryptProv = 0;
}
-#elif HAVE_GETENTROPY
+#elif defined(USE_GETENTROPY)
/* nothing to clean */
#else
dev_urandom_close();
--- a/pyconfig.h.in Fri Sep 11 12:38:27 2015 +0200
+++ b/pyconfig.h.in Fri Sep 11 13:06:42 2015 +0200
@@ -395,6 +395,9 @@
/* Define to 1 if you have the `getpwent' function. */
#undef HAVE_GETPWENT
+/* Define to 1 if the getrandom() function is available */
+#undef HAVE_GETRANDOM
+
/* Define to 1 if the Linux getrandom() syscall is available */
#undef HAVE_GETRANDOM_SYSCALL