mirror of https://github.com/python/cpython
Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
instead of reading /dev/urandom, to get pseudo-random bytes.
This commit is contained in:
parent
3c6fe4da88
commit
4d6a3d6c01
|
@ -27,6 +27,7 @@ import codecs
|
||||||
import decimal
|
import decimal
|
||||||
import fractions
|
import fractions
|
||||||
import pickle
|
import pickle
|
||||||
|
import sysconfig
|
||||||
try:
|
try:
|
||||||
import threading
|
import threading
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -1103,6 +1104,12 @@ class URandomTests(unittest.TestCase):
|
||||||
data2 = self.get_urandom_subprocess(16)
|
data2 = self.get_urandom_subprocess(16)
|
||||||
self.assertNotEqual(data1, data2)
|
self.assertNotEqual(data1, data2)
|
||||||
|
|
||||||
|
|
||||||
|
HAVE_GETENTROPY = (sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
|
||||||
|
|
||||||
|
@unittest.skipIf(HAVE_GETENTROPY,
|
||||||
|
"getentropy() does not use a file descriptor")
|
||||||
|
class URandomFDTests(unittest.TestCase):
|
||||||
@unittest.skipUnless(resource, "test requires the resource module")
|
@unittest.skipUnless(resource, "test requires the resource module")
|
||||||
def test_urandom_failure(self):
|
def test_urandom_failure(self):
|
||||||
# Check urandom() failing when it is not able to open /dev/random.
|
# Check urandom() failing when it is not able to open /dev/random.
|
||||||
|
|
|
@ -196,6 +196,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
|
||||||
|
instead of reading /dev/urandom, to get pseudo-random bytes.
|
||||||
|
|
||||||
- Issue #19104: pprint now produces evaluable output for wrapped strings.
|
- Issue #19104: pprint now produces evaluable output for wrapped strings.
|
||||||
|
|
||||||
- Issue #23071: Added missing names to codecs.__all__. Patch by Martin Panter.
|
- Issue #23071: Added missing names to codecs.__all__. Patch by Martin Panter.
|
||||||
|
|
|
@ -36,7 +36,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
|
/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
|
||||||
API. Return 0 on success, or -1 on error. */
|
API. Return 0 on success, or raise an exception and return -1 on error. */
|
||||||
static int
|
static int
|
||||||
win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
|
win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
|
||||||
{
|
{
|
||||||
|
@ -66,10 +66,35 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* MS_WINDOWS */
|
|
||||||
|
|
||||||
|
#elif HAVE_GETENTROPY
|
||||||
|
/* Fill buffer with size pseudo-random bytes generated by getentropy().
|
||||||
|
Return 0 on success, or raise an exception and return -1 on error.
|
||||||
|
|
||||||
#ifndef MS_WINDOWS
|
If fatal is nonzero, call Py_FatalError() instead of raising an exception
|
||||||
|
on error. */
|
||||||
|
static int
|
||||||
|
py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)
|
||||||
|
{
|
||||||
|
while (size > 0) {
|
||||||
|
Py_ssize_t len = Py_MIN(size, 256);
|
||||||
|
int res = getentropy(buffer, len);
|
||||||
|
if (res < 0) {
|
||||||
|
if (fatal) {
|
||||||
|
Py_FatalError("getentropy() failed");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer += len;
|
||||||
|
size -= len;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
static struct {
|
static struct {
|
||||||
int fd;
|
int fd;
|
||||||
dev_t st_dev;
|
dev_t st_dev;
|
||||||
|
@ -201,7 +226,7 @@ dev_urandom_close(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* HAVE_GETENTROPY */
|
||||||
|
|
||||||
/* Fill buffer with pseudo-random bytes generated by a linear congruent
|
/* Fill buffer with pseudo-random bytes generated by a linear congruent
|
||||||
generator (LCG):
|
generator (LCG):
|
||||||
|
@ -242,6 +267,8 @@ _PyOS_URandom(void *buffer, Py_ssize_t size)
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
return win32_urandom((unsigned char *)buffer, size, 1);
|
return win32_urandom((unsigned char *)buffer, size, 1);
|
||||||
|
#elif HAVE_GETENTROPY
|
||||||
|
return py_getentropy(buffer, size, 0);
|
||||||
#else
|
#else
|
||||||
return dev_urandom_python((char*)buffer, size);
|
return dev_urandom_python((char*)buffer, size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -287,6 +314,8 @@ _PyRandom_Init(void)
|
||||||
else {
|
else {
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
(void)win32_urandom(secret, secret_size, 0);
|
(void)win32_urandom(secret, secret_size, 0);
|
||||||
|
#elif HAVE_GETENTROPY
|
||||||
|
(void)py_getentropy(secret, secret_size, 1);
|
||||||
#else
|
#else
|
||||||
dev_urandom_noraise(secret, secret_size);
|
dev_urandom_noraise(secret, secret_size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -301,6 +330,8 @@ _PyRandom_Fini(void)
|
||||||
CryptReleaseContext(hCryptProv, 0);
|
CryptReleaseContext(hCryptProv, 0);
|
||||||
hCryptProv = 0;
|
hCryptProv = 0;
|
||||||
}
|
}
|
||||||
|
#elif HAVE_GETENTROPY
|
||||||
|
/* nothing to clean */
|
||||||
#else
|
#else
|
||||||
dev_urandom_close();
|
dev_urandom_close();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10697,7 +10697,7 @@ fi
|
||||||
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
|
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
|
||||||
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
||||||
futimens futimes gai_strerror \
|
futimens futimes gai_strerror getentropy \
|
||||||
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
|
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
|
||||||
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
||||||
if_nameindex \
|
if_nameindex \
|
||||||
|
|
|
@ -3004,7 +3004,7 @@ fi
|
||||||
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
|
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
|
||||||
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
||||||
futimens futimes gai_strerror \
|
futimens futimes gai_strerror getentropy \
|
||||||
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
|
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
|
||||||
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
||||||
if_nameindex \
|
if_nameindex \
|
||||||
|
|
|
@ -332,6 +332,9 @@
|
||||||
/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
|
/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
|
||||||
#undef HAVE_GETC_UNLOCKED
|
#undef HAVE_GETC_UNLOCKED
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getentropy' function. */
|
||||||
|
#undef HAVE_GETENTROPY
|
||||||
|
|
||||||
/* Define to 1 if you have the `getgrouplist' function. */
|
/* Define to 1 if you have the `getgrouplist' function. */
|
||||||
#undef HAVE_GETGROUPLIST
|
#undef HAVE_GETGROUPLIST
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue