python: update to 3.5.3

Prior versions of python do not support openssl 1.1; updating to
Python 3.6 on the other hand is a lot more involved, and so should
be done by a specialist/maintainer.

LICENSE checksum change due to copyright years.

Drop upstreamed python3-fix-CVE-2016-1000110.patch

Rebase upstream-random-fixes.patch (taken from
ff558f5aba )

Rebase 0001-Do-not-use-the-shell-version-of-python-config-that-w.patch

Rebase 000-cross-compile.patch

(From OE-Core rev: b7b982a29e5d14c558b5fc25b4dc727810510ade)

Signed-off-by: Alexander Kanavin <alexander.kanavin@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Alexander Kanavin
2017-05-10 17:13:19 +03:00
committed by Richard Purdie
parent 3266238516
commit 74684e30ea
6 changed files with 181 additions and 340 deletions

View File

@@ -1,21 +1,7 @@
This patch updates random.c to match upstream python's code at revision
8125d9a8152b. This addresses various issues around problems with glibc 2.24
and 2.25 such that python would fail to start with:
[rpurdie@centos7 ~]$ /tmp/t2/sysroots/x86_64-pokysdk-linux/usr/bin/python3
Fatal Python error: getentropy() failed
Aborted
(taken from our buildtools-tarball also breaks eSDK)
Upstream-Status: Backport
# HG changeset patch
# User Victor Stinner <victor.stinner@gmail.com>
# Date 1483957133 -3600
# Node ID 8125d9a8152b79e712cb09c7094b9129b9bcea86
# Parent 337461574c90281630751b6095c4e1baf380cf7d
Issue #29157: Prefer getrandom() over getentropy()
From 035ba5da3e53e45c712b39fe1f6fb743e697c032 Mon Sep 17 00:00:00 2001
From: Victor Stinner <victor.stinner@gmail.com>
Date: Mon, 9 Jan 2017 11:18:53 +0100
Subject: [PATCH] Issue #29157: Prefer getrandom() over getentropy()
Copy and then adapt Python/random.c from default branch. Difference between 3.5
and default branches:
@@ -26,12 +12,17 @@ and default branches:
* Python 3.5 has no _PyOS_URandomNonblock() function: _PyOS_URandom()
works in non-blocking mode on Python 3.5
RP 2017/1/22
Upstream-Status: Backport [https://github.com/python/cpython/commit/035ba5da3e53e45c712b39fe1f6fb743e697c032]
Signed-off-by: Alexander Kanavin <alexander.kanavin@intel.com>
Index: Python-3.5.2/Python/random.c
===================================================================
--- Python-3.5.2.orig/Python/random.c
+++ Python-3.5.2/Python/random.c
---
Python/random.c | 494 +++++++++++++++++++++++++++++++++-----------------------
1 file changed, 294 insertions(+), 200 deletions(-)
diff --git a/Python/random.c b/Python/random.c
index d203939..31f61d0 100644
--- a/Python/random.c
+++ b/Python/random.c
@@ -1,6 +1,9 @@
#include "Python.h"
#ifdef MS_WINDOWS
@@ -42,7 +33,7 @@ Index: Python-3.5.2/Python/random.c
#else
# include <fcntl.h>
# ifdef HAVE_SYS_STAT_H
@@ -36,10 +39,9 @@ win32_urandom_init(int raise)
@@ -37,10 +40,9 @@ win32_urandom_init(int raise)
return 0;
error:
@@ -55,7 +46,7 @@ Index: Python-3.5.2/Python/random.c
return -1;
}
@@ -52,8 +54,9 @@ win32_urandom(unsigned char *buffer, Py_
@@ -53,8 +55,9 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
if (hCryptProv == 0)
{
@@ -66,7 +57,7 @@ Index: Python-3.5.2/Python/random.c
}
while (size > 0)
@@ -62,11 +65,9 @@ win32_urandom(unsigned char *buffer, Py_
@@ -63,11 +66,9 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
{
/* CryptGenRandom() failed */
@@ -80,7 +71,7 @@ Index: Python-3.5.2/Python/random.c
return -1;
}
buffer += chunk;
@@ -75,55 +76,29 @@ win32_urandom(unsigned char *buffer, Py_
@@ -76,58 +77,23 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
return 0;
}
@@ -129,13 +120,19 @@ Index: Python-3.5.2/Python/random.c
#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
#define PY_GETRANDOM 1
-/* Call getrandom()
+/* Call getrandom() to get random bytes:
+
+ - Return 1 on success
- Return 1 on success
- - 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.
+ - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
+ or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
+ initialized yet).
+ - Raise an exception (if raise is non-zero) and return -1 on error:
- 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. */
+ if getrandom() failed with EINTR, raise is non-zero and the Python signal
+ handler raised an exception, or if getrandom() failed with a different
+ error.
@@ -144,26 +141,16 @@ Index: Python-3.5.2/Python/random.c
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 newer, or Solaris 11.3 or newer */
+ /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
+ failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
+ 11.3 or newer */
static int getrandom_works = 1;
/* getrandom() on Linux will block if called before the kernel has
@@ -132,84 +107,165 @@ py_getrandom(void *buffer, Py_ssize_t si
@@ -142,16 +108,19 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
* see https://bugs.python.org/issue26839. To avoid this, use the
* GRND_NONBLOCK flag. */
const int flags = GRND_NONBLOCK;
- int n;
+ char *dest;
+ long n;
long n;
- if (!getrandom_works)
+ if (!getrandom_works) {
if (!getrandom_works) {
return 0;
+ }
}
+ dest = buffer;
while (0 < size) {
@@ -174,11 +161,8 @@ Index: Python-3.5.2/Python/random.c
+ requested. */
n = Py_MIN(size, 1024);
#else
- n = size;
+ n = Py_MIN(size, LONG_MAX);
#endif
errno = 0;
n = Py_MIN(size, LONG_MAX);
@@ -161,34 +130,35 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
#ifdef HAVE_GETRANDOM
if (raise) {
Py_BEGIN_ALLOW_THREADS
@@ -209,56 +193,45 @@ Index: Python-3.5.2/Python/random.c
#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. */
+ /* ENOSYS: the syscall is not supported by the kernel.
+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
+ or something else. */
+ if (errno == ENOSYS || errno == EPERM) {
if (errno == ENOSYS || errno == EPERM) {
getrandom_works = 0;
return 0;
}
+
if (errno == EAGAIN) {
- /* If we failed with EAGAIN, the entropy pool was
- * uninitialized. In this case, we return failure to fall
- * back to reading from /dev/urandom.
- *
- * Note: In this case the data read will not be random so
- * should not be used for cryptographic purposes. Retaining
- * the existing semantics for practical purposes. */
+ /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system
+ urandom is not initialiazed yet. In this case, fall back on
+ reading from /dev/urandom.
+
+ Note: In this case the data read will not be random so
+ should not be used for cryptographic purposes. Retaining
+ the existing semantics for practical purposes. */
getrandom_works = 0;
return 0;
/* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system
urandom is not initialiazed yet. In this case, fall back on
@@ -202,169 +172,225 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
}
if (errno == EINTR) {
- if (PyErr_CheckSignals()) {
- if (!raise)
- if (!raise) {
- Py_FatalError("getrandom() interrupted by a signal");
- return -1;
+ if (raise) {
+ if (PyErr_CheckSignals()) {
+ return -1;
+ }
}
- return -1;
}
- /* retry getrandom() */
+
+ /* retry getrandom() if it was interrupted by a signal */
continue;
}
- if (raise)
+ if (raise) {
if (raise) {
PyErr_SetFromErrno(PyExc_OSError);
- else
}
- else {
- Py_FatalError("getrandom() failed");
+ }
- }
return -1;
}
@@ -269,12 +242,19 @@ Index: Python-3.5.2/Python/random.c
return 1;
}
-#endif
+
-static struct {
- int fd;
- dev_t st_dev;
- ino_t st_ino;
-} urandom_cache = { -1 };
+#elif defined(HAVE_GETENTROPY)
+#define PY_GETENTROPY 1
+
+/* Fill buffer with size pseudo-random bytes generated by getentropy():
+
-/* Read 'size' random bytes from py_getrandom(). Fall back on reading from
- /dev/urandom if getrandom() is not available.
+ - Return 1 on success
+ - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
+ EPERM).
@@ -282,25 +262,47 @@ Index: Python-3.5.2/Python/random.c
+ if getentropy() failed with EINTR, raise is non-zero and the Python signal
+ handler raised an exception, or if getentropy() failed with a different
+ error.
+
- Call Py_FatalError() on error. */
-static void
-dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size)
+ getentropy() is retried if it failed with EINTR: interrupted by a signal. */
+static int
+py_getentropy(char *buffer, Py_ssize_t size, int raise)
+{
{
- int fd;
- Py_ssize_t n;
+ /* Is getentropy() supported by the running kernel? Set to 0 if
+ getentropy() failed with ENOSYS or EPERM. */
+ static int getentropy_works = 1;
+
- assert (0 < size);
-
-#ifdef PY_GETRANDOM
- if (py_getrandom(buffer, size, 0) == 1) {
- return;
+ if (!getentropy_works) {
+ return 0;
+ }
+
}
- /* getrandom() failed with ENOSYS or EPERM,
- fall back on reading /dev/urandom */
-#endif
- fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
- if (fd < 0) {
- Py_FatalError("Failed to open /dev/urandom");
- }
+ while (size > 0) {
+ /* getentropy() is limited to returning up to 256 bytes. Call it
+ multiple times if more bytes are requested. */
+ Py_ssize_t len = Py_MIN(size, 256);
+ int res;
+
- while (0 < size)
- {
- do {
- n = read(fd, buffer, (size_t)size);
- } while (n < 0 && errno == EINTR);
+ if (raise) {
+ Py_BEGIN_ALLOW_THREADS
+ res = getentropy(buffer, len);
@@ -309,7 +311,11 @@ Index: Python-3.5.2/Python/random.c
+ else {
+ res = getentropy(buffer, len);
+ }
+
- if (n <= 0) {
- /* read() failed or returned 0 bytes */
- Py_FatalError("Failed to read bytes from /dev/urandom");
- break;
+ if (res < 0) {
+ /* ENOSYS: the syscall is not supported by the running kernel.
+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
@@ -334,71 +340,44 @@ Index: Python-3.5.2/Python/random.c
+ PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return -1;
+ }
}
- buffer += n;
- size -= n;
+
+ buffer += len;
+ size -= len;
+ }
}
- close(fd);
+ return 1;
+}
}
+#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
-/* Read 'size' random bytes from py_getrandom(). Fall back on reading from
- /dev/urandom if getrandom() is not available.
- Return 0 on success. Raise an exception and return -1 on error. */
+static struct {
+ int fd;
+ dev_t st_dev;
+ ino_t st_ino;
+} urandom_cache = { -1 };
+
static struct {
int fd;
@@ -217,127 +273,123 @@ static struct {
ino_t st_ino;
} urandom_cache = { -1 };
+/* Read random bytes from the /dev/urandom device:
-/* Read size bytes from /dev/urandom into buffer.
- Call Py_FatalError() on error. */
-static void
-dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size)
-{
- int fd;
- Py_ssize_t n;
+
+ - Return 0 on success
+ - Raise an exception (if raise is non-zero) and return -1 on error
- assert (0 < size);
+
+ Possible causes of errors:
-#ifdef PY_GETRANDOM
- if (py_getrandom(buffer, size, 0) == 1)
- return;
- /* getrandom() is not supported by the running kernel, fall back
- * on reading /dev/urandom */
-#endif
+
+ - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
+ was not found. For example, it was removed manually or not exposed in a
+ chroot or container.
+ - open() failed with a different error
+ - fstat() failed
+ - read() failed or returned 0
- fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
- if (fd < 0)
- Py_FatalError("Failed to open /dev/urandom");
+
+ read() is retried if it failed with EINTR: interrupted by a signal.
- while (0 < size)
- {
- do {
- n = read(fd, buffer, (size_t)size);
- } while (n < 0 && errno == EINTR);
- if (n <= 0)
- {
- /* stop on error or if read(size) returned 0 */
- Py_FatalError("Failed to read bytes from /dev/urandom");
- break;
- }
- buffer += n;
- size -= (Py_ssize_t)n;
- }
- close(fd);
-}
+
+ The file descriptor of the device is kept open between calls to avoid using
+ many file descriptors when run in parallel from multiple threads:
+ see the issue #18756.
@@ -406,9 +385,7 @@ Index: Python-3.5.2/Python/random.c
+ st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
+ check if the file descriptor was replaced by a different file (which is
+ likely a bug in the application): see the issue #21207.
-/* Read size bytes from /dev/urandom into buffer.
- Return 0 on success, raise an exception and return -1 on error. */
+
+ If the file descriptor was closed or replaced, open a new file descriptor
+ but don't close the old file descriptor: it probably points to something
+ important for some third-party code. */
@@ -422,22 +399,24 @@ Index: Python-3.5.2/Python/random.c
-#ifdef PY_GETRANDOM
- int res;
-#endif
-
- if (size <= 0)
- return 0;
+ if (raise) {
+ struct _Py_stat_struct st;
-#ifdef PY_GETRANDOM
- res = py_getrandom(buffer, size, 1);
- if (res < 0)
- if (res < 0) {
- return -1;
- if (res == 1)
- }
- 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
-
+ if (raise) {
+ struct _Py_stat_struct st;
- if (urandom_cache.fd >= 0) {
- /* Does the fd point to the same thing as before? (issue #21207) */
- if (_Py_fstat_noraise(urandom_cache.fd, &st)
@@ -516,8 +495,9 @@ Index: Python-3.5.2/Python/random.c
- do {
- n = _Py_read(fd, buffer, (size_t)size);
- if (n == -1)
- if (n == -1) {
- return -1;
- }
- if (n == 0) {
- PyErr_Format(PyExc_RuntimeError,
- "Failed to read %zi bytes from /dev/urandom",
@@ -566,7 +546,7 @@ Index: Python-3.5.2/Python/random.c
return 0;
}
@@ -349,8 +401,8 @@ dev_urandom_close(void)
@@ -376,8 +402,8 @@ dev_urandom_close(void)
urandom_cache.fd = -1;
}
}
@@ -576,7 +556,7 @@ Index: Python-3.5.2/Python/random.c
/* Fill buffer with pseudo-random bytes generated by a linear congruent
generator (LCG):
@@ -373,29 +425,98 @@ lcg_urandom(unsigned int x0, unsigned ch
@@ -400,31 +426,100 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
}
}
@@ -661,7 +641,7 @@ Index: Python-3.5.2/Python/random.c
#else
- return dev_urandom_python((char*)buffer, size);
+ res = py_getentropy(buffer, size, raise);
#endif
+#endif
+ if (res < 0) {
+ return -1;
+ }
@@ -673,9 +653,9 @@ Index: Python-3.5.2/Python/random.c
+#endif
+
+ return dev_urandom(buffer, size, raise);
+#endif
+}
+
#endif
}
+/* Fill buffer with size pseudo-random bytes from the operating system random
+ number generator (RNG). It is suitable for most cryptographic purposes
+ except long living private keys for asymmetric encryption.
@@ -685,10 +665,12 @@ Index: Python-3.5.2/Python/random.c
+_PyOS_URandom(void *buffer, Py_ssize_t size)
+{
+ return pyurandom(buffer, size, 1);
}
+}
+
void
@@ -436,13 +557,14 @@ _PyRandom_Init(void)
_PyRandom_Init(void)
{
@@ -463,13 +558,14 @@ _PyRandom_Init(void)
}
}
else {
@@ -710,7 +692,7 @@ Index: Python-3.5.2/Python/random.c
}
}
@@ -454,8 +576,6 @@ _PyRandom_Fini(void)
@@ -481,8 +577,6 @@ _PyRandom_Fini(void)
CryptReleaseContext(hCryptProv, 0);
hCryptProv = 0;
}