summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/python/python3/upstream-random-fixes.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/python/python3/upstream-random-fixes.patch')
-rw-r--r--meta/recipes-devtools/python/python3/upstream-random-fixes.patch288
1 files changed, 135 insertions, 153 deletions
diff --git a/meta/recipes-devtools/python/python3/upstream-random-fixes.patch b/meta/recipes-devtools/python/python3/upstream-random-fixes.patch
index 0d9152ccd7..9b40e8ac9f 100644
--- a/meta/recipes-devtools/python/python3/upstream-random-fixes.patch
+++ b/meta/recipes-devtools/python/python3/upstream-random-fixes.patch
@@ -1,21 +1,7 @@
1This patch updates random.c to match upstream python's code at revision 1From 035ba5da3e53e45c712b39fe1f6fb743e697c032 Mon Sep 17 00:00:00 2001
28125d9a8152b. This addresses various issues around problems with glibc 2.24 2From: Victor Stinner <victor.stinner@gmail.com>
3and 2.25 such that python would fail to start with: 3Date: Mon, 9 Jan 2017 11:18:53 +0100
4 4Subject: [PATCH] Issue #29157: Prefer getrandom() over getentropy()
5[rpurdie@centos7 ~]$ /tmp/t2/sysroots/x86_64-pokysdk-linux/usr/bin/python3
6Fatal Python error: getentropy() failed
7Aborted
8
9(taken from our buildtools-tarball also breaks eSDK)
10
11Upstream-Status: Backport
12
13# HG changeset patch
14# User Victor Stinner <victor.stinner@gmail.com>
15# Date 1483957133 -3600
16# Node ID 8125d9a8152b79e712cb09c7094b9129b9bcea86
17# Parent 337461574c90281630751b6095c4e1baf380cf7d
18Issue #29157: Prefer getrandom() over getentropy()
19 5
20Copy and then adapt Python/random.c from default branch. Difference between 3.5 6Copy and then adapt Python/random.c from default branch. Difference between 3.5
21and default branches: 7and default branches:
@@ -26,12 +12,17 @@ and default branches:
26* Python 3.5 has no _PyOS_URandomNonblock() function: _PyOS_URandom() 12* Python 3.5 has no _PyOS_URandomNonblock() function: _PyOS_URandom()
27 works in non-blocking mode on Python 3.5 13 works in non-blocking mode on Python 3.5
28 14
29RP 2017/1/22 15Upstream-Status: Backport [https://github.com/python/cpython/commit/035ba5da3e53e45c712b39fe1f6fb743e697c032]
16Signed-off-by: Alexander Kanavin <alexander.kanavin@intel.com>
17
18---
19 Python/random.c | 494 +++++++++++++++++++++++++++++++++-----------------------
20 1 file changed, 294 insertions(+), 200 deletions(-)
30 21
31Index: Python-3.5.2/Python/random.c 22diff --git a/Python/random.c b/Python/random.c
32=================================================================== 23index d203939..31f61d0 100644
33--- Python-3.5.2.orig/Python/random.c 24--- a/Python/random.c
34+++ Python-3.5.2/Python/random.c 25+++ b/Python/random.c
35@@ -1,6 +1,9 @@ 26@@ -1,6 +1,9 @@
36 #include "Python.h" 27 #include "Python.h"
37 #ifdef MS_WINDOWS 28 #ifdef MS_WINDOWS
@@ -42,7 +33,7 @@ Index: Python-3.5.2/Python/random.c
42 #else 33 #else
43 # include <fcntl.h> 34 # include <fcntl.h>
44 # ifdef HAVE_SYS_STAT_H 35 # ifdef HAVE_SYS_STAT_H
45@@ -36,10 +39,9 @@ win32_urandom_init(int raise) 36@@ -37,10 +40,9 @@ win32_urandom_init(int raise)
46 return 0; 37 return 0;
47 38
48 error: 39 error:
@@ -55,7 +46,7 @@ Index: Python-3.5.2/Python/random.c
55 return -1; 46 return -1;
56 } 47 }
57 48
58@@ -52,8 +54,9 @@ win32_urandom(unsigned char *buffer, Py_ 49@@ -53,8 +55,9 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
59 50
60 if (hCryptProv == 0) 51 if (hCryptProv == 0)
61 { 52 {
@@ -66,7 +57,7 @@ Index: Python-3.5.2/Python/random.c
66 } 57 }
67 58
68 while (size > 0) 59 while (size > 0)
69@@ -62,11 +65,9 @@ win32_urandom(unsigned char *buffer, Py_ 60@@ -63,11 +66,9 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
70 if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer)) 61 if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
71 { 62 {
72 /* CryptGenRandom() failed */ 63 /* CryptGenRandom() failed */
@@ -80,7 +71,7 @@ Index: Python-3.5.2/Python/random.c
80 return -1; 71 return -1;
81 } 72 }
82 buffer += chunk; 73 buffer += chunk;
83@@ -75,55 +76,29 @@ win32_urandom(unsigned char *buffer, Py_ 74@@ -76,58 +77,23 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
84 return 0; 75 return 0;
85 } 76 }
86 77
@@ -129,13 +120,19 @@ Index: Python-3.5.2/Python/random.c
129 #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) 120 #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
130 #define PY_GETRANDOM 1 121 #define PY_GETRANDOM 1
131 122
123-/* Call getrandom()
132+/* Call getrandom() to get random bytes: 124+/* Call getrandom() to get random bytes:
133+ 125+
134+ - Return 1 on success 126 - Return 1 on success
127- - Return 0 if getrandom() syscall is not available (failed with ENOSYS or
128- EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom
129- not initialized yet) and raise=0.
135+ - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM), 130+ - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
136+ or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not 131+ or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
137+ initialized yet). 132+ initialized yet).
138+ - Raise an exception (if raise is non-zero) and return -1 on error: 133 - Raise an exception (if raise is non-zero) and return -1 on error:
134- getrandom() failed with EINTR and the Python signal handler raised an
135- exception, or getrandom() failed with a different error. */
139+ if getrandom() failed with EINTR, raise is non-zero and the Python signal 136+ if getrandom() failed with EINTR, raise is non-zero and the Python signal
140+ handler raised an exception, or if getrandom() failed with a different 137+ handler raised an exception, or if getrandom() failed with a different
141+ error. 138+ error.
@@ -144,26 +141,16 @@ Index: Python-3.5.2/Python/random.c
144 static int 141 static int
145 py_getrandom(void *buffer, Py_ssize_t size, int raise) 142 py_getrandom(void *buffer, Py_ssize_t size, int raise)
146 { 143 {
147- /* Is getrandom() supported by the running kernel? 144@@ -142,16 +108,19 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
148- * Need Linux kernel 3.17 or newer, or Solaris 11.3 or newer */
149+ /* Is getrandom() supported by the running kernel? Set to 0 if getrandom()
150+ failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris
151+ 11.3 or newer */
152 static int getrandom_works = 1;
153
154 /* getrandom() on Linux will block if called before the kernel has
155@@ -132,84 +107,165 @@ py_getrandom(void *buffer, Py_ssize_t si
156 * see https://bugs.python.org/issue26839. To avoid this, use the 145 * see https://bugs.python.org/issue26839. To avoid this, use the
157 * GRND_NONBLOCK flag. */ 146 * GRND_NONBLOCK flag. */
158 const int flags = GRND_NONBLOCK; 147 const int flags = GRND_NONBLOCK;
159- int n;
160+ char *dest; 148+ char *dest;
161+ long n; 149 long n;
162 150
163- if (!getrandom_works) 151 if (!getrandom_works) {
164+ if (!getrandom_works) {
165 return 0; 152 return 0;
166+ } 153 }
167 154
168+ dest = buffer; 155+ dest = buffer;
169 while (0 < size) { 156 while (0 < size) {
@@ -174,11 +161,8 @@ Index: Python-3.5.2/Python/random.c
174+ requested. */ 161+ requested. */
175 n = Py_MIN(size, 1024); 162 n = Py_MIN(size, 1024);
176 #else 163 #else
177- n = size; 164 n = Py_MIN(size, LONG_MAX);
178+ n = Py_MIN(size, LONG_MAX); 165@@ -161,34 +130,35 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
179 #endif
180
181 errno = 0;
182 #ifdef HAVE_GETRANDOM 166 #ifdef HAVE_GETRANDOM
183 if (raise) { 167 if (raise) {
184 Py_BEGIN_ALLOW_THREADS 168 Py_BEGIN_ALLOW_THREADS
@@ -209,56 +193,45 @@ Index: Python-3.5.2/Python/random.c
209 #endif 193 #endif
210 194
211 if (n < 0) { 195 if (n < 0) {
212- if (errno == ENOSYS) { 196- /* ENOSYS: getrandom() syscall not supported by the kernel (but
197- * maybe supported by the host which built Python). EPERM:
198- * getrandom() syscall blocked by SECCOMP or something else. */
213+ /* ENOSYS: the syscall is not supported by the kernel. 199+ /* ENOSYS: the syscall is not supported by the kernel.
214+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP) 200+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
215+ or something else. */ 201+ or something else. */
216+ if (errno == ENOSYS || errno == EPERM) { 202 if (errno == ENOSYS || errno == EPERM) {
217 getrandom_works = 0; 203 getrandom_works = 0;
218 return 0; 204 return 0;
219 } 205 }
220+ 206+
221 if (errno == EAGAIN) { 207 if (errno == EAGAIN) {
222- /* If we failed with EAGAIN, the entropy pool was 208 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system
223- * uninitialized. In this case, we return failure to fall 209 urandom is not initialiazed yet. In this case, fall back on
224- * back to reading from /dev/urandom. 210@@ -202,169 +172,225 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
225- *
226- * Note: In this case the data read will not be random so
227- * should not be used for cryptographic purposes. Retaining
228- * the existing semantics for practical purposes. */
229+ /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system
230+ urandom is not initialiazed yet. In this case, fall back on
231+ reading from /dev/urandom.
232+
233+ Note: In this case the data read will not be random so
234+ should not be used for cryptographic purposes. Retaining
235+ the existing semantics for practical purposes. */
236 getrandom_works = 0;
237 return 0;
238 } 211 }
239 212
240 if (errno == EINTR) { 213 if (errno == EINTR) {
241- if (PyErr_CheckSignals()) { 214- if (PyErr_CheckSignals()) {
242- if (!raise) 215- if (!raise) {
243- Py_FatalError("getrandom() interrupted by a signal"); 216- Py_FatalError("getrandom() interrupted by a signal");
244- return -1;
245+ if (raise) { 217+ if (raise) {
246+ if (PyErr_CheckSignals()) { 218+ if (PyErr_CheckSignals()) {
247+ return -1; 219+ return -1;
248+ } 220 }
221- return -1;
249 } 222 }
223
250- /* retry getrandom() */ 224- /* retry getrandom() */
251+
252+ /* retry getrandom() if it was interrupted by a signal */ 225+ /* retry getrandom() if it was interrupted by a signal */
253 continue; 226 continue;
254 } 227 }
255 228
256- if (raise) 229 if (raise) {
257+ if (raise) {
258 PyErr_SetFromErrno(PyExc_OSError); 230 PyErr_SetFromErrno(PyExc_OSError);
259- else 231 }
232- else {
260- Py_FatalError("getrandom() failed"); 233- Py_FatalError("getrandom() failed");
261+ } 234- }
262 return -1; 235 return -1;
263 } 236 }
264 237
@@ -269,12 +242,19 @@ Index: Python-3.5.2/Python/random.c
269 return 1; 242 return 1;
270 } 243 }
271-#endif 244-#endif
272+ 245
246-static struct {
247- int fd;
248- dev_t st_dev;
249- ino_t st_ino;
250-} urandom_cache = { -1 };
273+#elif defined(HAVE_GETENTROPY) 251+#elif defined(HAVE_GETENTROPY)
274+#define PY_GETENTROPY 1 252+#define PY_GETENTROPY 1
275+ 253
276+/* Fill buffer with size pseudo-random bytes generated by getentropy(): 254+/* Fill buffer with size pseudo-random bytes generated by getentropy():
277+ 255
256-/* Read 'size' random bytes from py_getrandom(). Fall back on reading from
257- /dev/urandom if getrandom() is not available.
278+ - Return 1 on success 258+ - Return 1 on success
279+ - Return 0 if getentropy() syscall is not available (failed with ENOSYS or 259+ - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
280+ EPERM). 260+ EPERM).
@@ -282,25 +262,47 @@ Index: Python-3.5.2/Python/random.c
282+ if getentropy() failed with EINTR, raise is non-zero and the Python signal 262+ if getentropy() failed with EINTR, raise is non-zero and the Python signal
283+ handler raised an exception, or if getentropy() failed with a different 263+ handler raised an exception, or if getentropy() failed with a different
284+ error. 264+ error.
285+ 265
266- Call Py_FatalError() on error. */
267-static void
268-dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size)
286+ getentropy() is retried if it failed with EINTR: interrupted by a signal. */ 269+ getentropy() is retried if it failed with EINTR: interrupted by a signal. */
287+static int 270+static int
288+py_getentropy(char *buffer, Py_ssize_t size, int raise) 271+py_getentropy(char *buffer, Py_ssize_t size, int raise)
289+{ 272 {
273- int fd;
274- Py_ssize_t n;
290+ /* Is getentropy() supported by the running kernel? Set to 0 if 275+ /* Is getentropy() supported by the running kernel? Set to 0 if
291+ getentropy() failed with ENOSYS or EPERM. */ 276+ getentropy() failed with ENOSYS or EPERM. */
292+ static int getentropy_works = 1; 277+ static int getentropy_works = 1;
293+ 278
279- assert (0 < size);
280-
281-#ifdef PY_GETRANDOM
282- if (py_getrandom(buffer, size, 0) == 1) {
283- return;
294+ if (!getentropy_works) { 284+ if (!getentropy_works) {
295+ return 0; 285+ return 0;
296+ } 286 }
297+ 287- /* getrandom() failed with ENOSYS or EPERM,
288- fall back on reading /dev/urandom */
289-#endif
290
291- fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
292- if (fd < 0) {
293- Py_FatalError("Failed to open /dev/urandom");
294- }
298+ while (size > 0) { 295+ while (size > 0) {
299+ /* getentropy() is limited to returning up to 256 bytes. Call it 296+ /* getentropy() is limited to returning up to 256 bytes. Call it
300+ multiple times if more bytes are requested. */ 297+ multiple times if more bytes are requested. */
301+ Py_ssize_t len = Py_MIN(size, 256); 298+ Py_ssize_t len = Py_MIN(size, 256);
302+ int res; 299+ int res;
303+ 300
301- while (0 < size)
302- {
303- do {
304- n = read(fd, buffer, (size_t)size);
305- } while (n < 0 && errno == EINTR);
304+ if (raise) { 306+ if (raise) {
305+ Py_BEGIN_ALLOW_THREADS 307+ Py_BEGIN_ALLOW_THREADS
306+ res = getentropy(buffer, len); 308+ res = getentropy(buffer, len);
@@ -309,7 +311,11 @@ Index: Python-3.5.2/Python/random.c
309+ else { 311+ else {
310+ res = getentropy(buffer, len); 312+ res = getentropy(buffer, len);
311+ } 313+ }
312+ 314
315- if (n <= 0) {
316- /* read() failed or returned 0 bytes */
317- Py_FatalError("Failed to read bytes from /dev/urandom");
318- break;
313+ if (res < 0) { 319+ if (res < 0) {
314+ /* ENOSYS: the syscall is not supported by the running kernel. 320+ /* ENOSYS: the syscall is not supported by the running kernel.
315+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP) 321+ EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
@@ -334,71 +340,44 @@ Index: Python-3.5.2/Python/random.c
334+ PyErr_SetFromErrno(PyExc_OSError); 340+ PyErr_SetFromErrno(PyExc_OSError);
335+ } 341+ }
336+ return -1; 342+ return -1;
337+ } 343 }
344- buffer += n;
345- size -= n;
338+ 346+
339+ buffer += len; 347+ buffer += len;
340+ size -= len; 348+ size -= len;
341+ } 349 }
350- close(fd);
342+ return 1; 351+ return 1;
343+} 352 }
344+#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */ 353+#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
345+
346 354
347 static struct { 355-/* Read 'size' random bytes from py_getrandom(). Fall back on reading from
348 int fd; 356- /dev/urandom if getrandom() is not available.
349@@ -217,127 +273,123 @@ static struct {
350 ino_t st_ino;
351 } urandom_cache = { -1 };
352 357
358- Return 0 on success. Raise an exception and return -1 on error. */
359+static struct {
360+ int fd;
361+ dev_t st_dev;
362+ ino_t st_ino;
363+} urandom_cache = { -1 };
364+
353+/* Read random bytes from the /dev/urandom device: 365+/* Read random bytes from the /dev/urandom device:
354 366+
355-/* Read size bytes from /dev/urandom into buffer.
356- Call Py_FatalError() on error. */
357-static void
358-dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size)
359-{
360- int fd;
361- Py_ssize_t n;
362+ - Return 0 on success 367+ - Return 0 on success
363+ - Raise an exception (if raise is non-zero) and return -1 on error 368+ - Raise an exception (if raise is non-zero) and return -1 on error
364 369+
365- assert (0 < size);
366+ Possible causes of errors: 370+ Possible causes of errors:
367 371+
368-#ifdef PY_GETRANDOM
369- if (py_getrandom(buffer, size, 0) == 1)
370- return;
371- /* getrandom() is not supported by the running kernel, fall back
372- * on reading /dev/urandom */
373-#endif
374+ - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device 372+ - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
375+ was not found. For example, it was removed manually or not exposed in a 373+ was not found. For example, it was removed manually or not exposed in a
376+ chroot or container. 374+ chroot or container.
377+ - open() failed with a different error 375+ - open() failed with a different error
378+ - fstat() failed 376+ - fstat() failed
379+ - read() failed or returned 0 377+ - read() failed or returned 0
380 378+
381- fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
382- if (fd < 0)
383- Py_FatalError("Failed to open /dev/urandom");
384+ read() is retried if it failed with EINTR: interrupted by a signal. 379+ read() is retried if it failed with EINTR: interrupted by a signal.
385 380+
386- while (0 < size)
387- {
388- do {
389- n = read(fd, buffer, (size_t)size);
390- } while (n < 0 && errno == EINTR);
391- if (n <= 0)
392- {
393- /* stop on error or if read(size) returned 0 */
394- Py_FatalError("Failed to read bytes from /dev/urandom");
395- break;
396- }
397- buffer += n;
398- size -= (Py_ssize_t)n;
399- }
400- close(fd);
401-}
402+ The file descriptor of the device is kept open between calls to avoid using 381+ The file descriptor of the device is kept open between calls to avoid using
403+ many file descriptors when run in parallel from multiple threads: 382+ many file descriptors when run in parallel from multiple threads:
404+ see the issue #18756. 383+ see the issue #18756.
@@ -406,9 +385,7 @@ Index: Python-3.5.2/Python/random.c
406+ st_dev and st_ino fields of the file descriptor (from fstat()) are cached to 385+ st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
407+ check if the file descriptor was replaced by a different file (which is 386+ check if the file descriptor was replaced by a different file (which is
408+ likely a bug in the application): see the issue #21207. 387+ likely a bug in the application): see the issue #21207.
409 388+
410-/* Read size bytes from /dev/urandom into buffer.
411- Return 0 on success, raise an exception and return -1 on error. */
412+ If the file descriptor was closed or replaced, open a new file descriptor 389+ If the file descriptor was closed or replaced, open a new file descriptor
413+ but don't close the old file descriptor: it probably points to something 390+ but don't close the old file descriptor: it probably points to something
414+ important for some third-party code. */ 391+ important for some third-party code. */
@@ -422,22 +399,24 @@ Index: Python-3.5.2/Python/random.c
422-#ifdef PY_GETRANDOM 399-#ifdef PY_GETRANDOM
423- int res; 400- int res;
424-#endif 401-#endif
425 402-
426- if (size <= 0) 403- if (size <= 0)
427- return 0; 404- return 0;
428+ if (raise) {
429+ struct _Py_stat_struct st;
430 405
431-#ifdef PY_GETRANDOM 406-#ifdef PY_GETRANDOM
432- res = py_getrandom(buffer, size, 1); 407- res = py_getrandom(buffer, size, 1);
433- if (res < 0) 408- if (res < 0) {
434- return -1; 409- return -1;
435- if (res == 1) 410- }
411- if (res == 1) {
436- return 0; 412- return 0;
437- /* getrandom() is not supported by the running kernel, fall back 413- }
438- * on reading /dev/urandom */ 414- /* getrandom() failed with ENOSYS or EPERM,
415- fall back on reading /dev/urandom */
439-#endif 416-#endif
440- 417+ if (raise) {
418+ struct _Py_stat_struct st;
419
441- if (urandom_cache.fd >= 0) { 420- if (urandom_cache.fd >= 0) {
442- /* Does the fd point to the same thing as before? (issue #21207) */ 421- /* Does the fd point to the same thing as before? (issue #21207) */
443- if (_Py_fstat_noraise(urandom_cache.fd, &st) 422- if (_Py_fstat_noraise(urandom_cache.fd, &st)
@@ -516,8 +495,9 @@ Index: Python-3.5.2/Python/random.c
516 495
517- do { 496- do {
518- n = _Py_read(fd, buffer, (size_t)size); 497- n = _Py_read(fd, buffer, (size_t)size);
519- if (n == -1) 498- if (n == -1) {
520- return -1; 499- return -1;
500- }
521- if (n == 0) { 501- if (n == 0) {
522- PyErr_Format(PyExc_RuntimeError, 502- PyErr_Format(PyExc_RuntimeError,
523- "Failed to read %zi bytes from /dev/urandom", 503- "Failed to read %zi bytes from /dev/urandom",
@@ -566,7 +546,7 @@ Index: Python-3.5.2/Python/random.c
566 return 0; 546 return 0;
567 } 547 }
568 548
569@@ -349,8 +401,8 @@ dev_urandom_close(void) 549@@ -376,8 +402,8 @@ dev_urandom_close(void)
570 urandom_cache.fd = -1; 550 urandom_cache.fd = -1;
571 } 551 }
572 } 552 }
@@ -576,7 +556,7 @@ Index: Python-3.5.2/Python/random.c
576 556
577 /* Fill buffer with pseudo-random bytes generated by a linear congruent 557 /* Fill buffer with pseudo-random bytes generated by a linear congruent
578 generator (LCG): 558 generator (LCG):
579@@ -373,29 +425,98 @@ lcg_urandom(unsigned int x0, unsigned ch 559@@ -400,31 +426,100 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
580 } 560 }
581 } 561 }
582 562
@@ -661,7 +641,7 @@ Index: Python-3.5.2/Python/random.c
661 #else 641 #else
662- return dev_urandom_python((char*)buffer, size); 642- return dev_urandom_python((char*)buffer, size);
663+ res = py_getentropy(buffer, size, raise); 643+ res = py_getentropy(buffer, size, raise);
664 #endif 644+#endif
665+ if (res < 0) { 645+ if (res < 0) {
666+ return -1; 646+ return -1;
667+ } 647+ }
@@ -673,9 +653,9 @@ Index: Python-3.5.2/Python/random.c
673+#endif 653+#endif
674+ 654+
675+ return dev_urandom(buffer, size, raise); 655+ return dev_urandom(buffer, size, raise);
676+#endif 656 #endif
677+} 657 }
678+ 658
679+/* Fill buffer with size pseudo-random bytes from the operating system random 659+/* Fill buffer with size pseudo-random bytes from the operating system random
680+ number generator (RNG). It is suitable for most cryptographic purposes 660+ number generator (RNG). It is suitable for most cryptographic purposes
681+ except long living private keys for asymmetric encryption. 661+ except long living private keys for asymmetric encryption.
@@ -685,10 +665,12 @@ Index: Python-3.5.2/Python/random.c
685+_PyOS_URandom(void *buffer, Py_ssize_t size) 665+_PyOS_URandom(void *buffer, Py_ssize_t size)
686+{ 666+{
687+ return pyurandom(buffer, size, 1); 667+ return pyurandom(buffer, size, 1);
688 } 668+}
689 669+
690 void 670 void
691@@ -436,13 +557,14 @@ _PyRandom_Init(void) 671 _PyRandom_Init(void)
672 {
673@@ -463,13 +558,14 @@ _PyRandom_Init(void)
692 } 674 }
693 } 675 }
694 else { 676 else {
@@ -710,7 +692,7 @@ Index: Python-3.5.2/Python/random.c
710 } 692 }
711 } 693 }
712 694
713@@ -454,8 +576,6 @@ _PyRandom_Fini(void) 695@@ -481,8 +577,6 @@ _PyRandom_Fini(void)
714 CryptReleaseContext(hCryptProv, 0); 696 CryptReleaseContext(hCryptProv, 0);
715 hCryptProv = 0; 697 hCryptProv = 0;
716 } 698 }