From 6bb1189dedf6516082bfc230bff3eafd8f9e4770 Mon Sep 17 00:00:00 2001 From: Miro Hrončok Date: Jan 05 2017 17:52:42 +0000 Subject: Don't blow up on EL7 kernel (random generator) (rhbz#1410175) --- diff --git a/00250-getentropy.patch b/00250-getentropy.patch new file mode 100644 index 0000000..6d0025a --- /dev/null +++ b/00250-getentropy.patch @@ -0,0 +1,171 @@ +diff -r ee1390c9b585 Python/random.c +--- a/Python/random.c Wed Jan 04 12:02:30 2017 +0100 ++++ b/Python/random.c Wed Jan 04 18:32:21 2017 +0100 +@@ -77,45 +77,8 @@ win32_urandom(unsigned char *buffer, Py_ + return 0; + } + +-/* Issue #25003: Don't use getentropy() on Solaris (available since +- * Solaris 11.3), it is blocking whereas os.urandom() should not block. */ +-#elif defined(HAVE_GETENTROPY) && !defined(sun) +-#define PY_GETENTROPY 1 +- +-/* Fill buffer with size pseudo-random bytes generated by getentropy(). +- Return 0 on success, or raise an exception and return -1 on error. +- +- If raise is zero, don't raise an exception on error. */ +-static int +-py_getentropy(char *buffer, Py_ssize_t size, int raise) +-{ +- while (size > 0) { +- Py_ssize_t len = Py_MIN(size, 256); +- int res; ++#else /* !MS_WINDOWS */ + +- if (raise) { +- Py_BEGIN_ALLOW_THREADS +- res = getentropy(buffer, len); +- Py_END_ALLOW_THREADS +- } +- else { +- res = getentropy(buffer, len); +- } +- +- if (res < 0) { +- if (raise) { +- PyErr_SetFromErrno(PyExc_OSError); +- } +- return -1; +- } +- +- buffer += len; +- size -= len; +- } +- return 0; +-} +- +-#else + + #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) + #define PY_GETRANDOM 1 +@@ -217,6 +180,59 @@ py_getrandom(void *buffer, Py_ssize_t si + } + return 1; + } ++ ++/* Issue #25003: Don't use getentropy() on Solaris (available since ++ * Solaris 11.3), it is blocking whereas os.urandom() should not block. */ ++#elif defined(HAVE_GETENTROPY) && !defined(sun) ++#define PY_GETENTROPY 1 ++ ++/* Fill buffer with size pseudo-random bytes generated by getentropy(). ++ Return 1 on success, or raise an exception and return -1 on error. ++ ++ If raise is zero, don't raise an exception on error. */ ++static int ++py_getentropy(char *buffer, Py_ssize_t size, int raise) ++{ ++ /* Is getentropy() supported by the running kernel? Set to 0 if ++ getentropy() failed with ENOSYS. */ ++ static int getentropy_works = 1; ++ ++ if (!getentropy_works) { ++ return 0; ++ } ++ ++ while (size > 0) { ++ Py_ssize_t len = Py_MIN(size, 256); ++ int res; ++ ++ if (raise) { ++ Py_BEGIN_ALLOW_THREADS ++ res = getentropy(buffer, len); ++ Py_END_ALLOW_THREADS ++ } ++ else { ++ res = getentropy(buffer, len); ++ } ++ ++ if (res < 0) { ++ /* ENOSYS: the inner syscall is not supported by the running ++ kernel. */ ++ if (errno == ENOSYS) { ++ getentropy_works = 0; ++ return 0; ++ } ++ ++ if (raise) { ++ PyErr_SetFromErrno(PyExc_OSError); ++ } ++ return -1; ++ } ++ ++ buffer += len; ++ size -= len; ++ } ++ return 1; ++} + #endif + + static struct { +@@ -236,7 +252,7 @@ dev_urandom(char *buffer, Py_ssize_t siz + { + int fd; + Py_ssize_t n; +-#ifdef PY_GETRANDOM ++#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) + int res; + #endif + +@@ -244,17 +260,20 @@ dev_urandom(char *buffer, Py_ssize_t siz + + #ifdef PY_GETRANDOM + res = py_getrandom(buffer, size, blocking, raise); ++#elif defined(PY_GETENTROPY) ++ res = py_getentropy(buffer, size, raise); ++#endif ++#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) + if (res < 0) { + return -1; + } + if (res == 1) { + return 0; + } +- /* getrandom() failed with ENOSYS or EPERM, +- fall back on reading /dev/urandom */ ++ /* function failed with ENOSYS or EPERM, fall back on reading ++ from /dev/urandom */ + #endif + +- + if (raise) { + struct _Py_stat_struct st; + +@@ -349,8 +368,8 @@ dev_urandom_close(void) + urandom_cache.fd = -1; + } + } ++#endif /* !MS_WINDOWS */ + +-#endif + + /* Fill buffer with pseudo-random bytes generated by a linear congruent + generator (LCG): +@@ -395,8 +414,6 @@ pyurandom(void *buffer, Py_ssize_t size, + + #ifdef MS_WINDOWS + return win32_urandom((unsigned char *)buffer, size, raise); +-#elif defined(PY_GETENTROPY) +- return py_getentropy(buffer, size, raise); + #else + return dev_urandom(buffer, size, blocking, raise); + #endif +@@ -491,8 +508,6 @@ void + CryptReleaseContext(hCryptProv, 0); + hCryptProv = 0; + } +-#elif defined(PY_GETENTROPY) +- /* nothing to clean */ + #else + dev_urandom_close(); + #endif diff --git a/python3.spec b/python3.spec index 14aaccf..43908f6 100644 --- a/python3.spec +++ b/python3.spec @@ -124,7 +124,7 @@ Summary: Version 3 of the Python programming language aka Python 3000 Name: python3 Version: %{pybasever}.0 -Release: 1%{?dist} +Release: 3%{?dist} License: Python Group: Development/Languages @@ -402,6 +402,12 @@ Patch243: 00243-fix-mips64-triplet.patch # Not yet fixed upstream: http://bugs.python.org/issue28787 Patch249: 00249-fix-out-of-tree-dtrace-builds.patch +# 00250 # +# After glibc-2.24.90, Python 3 failed to start on EL7 kernel +# rhbz#1410175: https://bugzilla.redhat.com/show_bug.cgi?id=1410175 +# http://bugs.python.org/issue29157 +Patch250: 00250-getentropy.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -639,6 +645,7 @@ sed -r -i s/'_PIP_VERSION = "[0-9.]+"'/'_PIP_VERSION = "%{pip_version}"'/ Lib/en %patch206 -p1 %patch243 -p1 %patch249 -p1 +%patch250 -p1 # Currently (2010-01-15), http://docs.python.org/library is for 2.6, and there # are many differences between 2.6 and the Python 3 library. @@ -1557,6 +1564,9 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Thu Jan 05 2017 Miro Hrončok - 3.6.0-2 +- Don't blow up on EL7 kernel (random generator) (rhbz#1410175) + * Tue Dec 27 2016 Charalampos Stratakis - 3.6.0-1 - Update to Python 3.6.0 final