summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-09-06 23:33:52 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-09-06 23:33:52 (GMT)
commite66987e626cfce8292c39d5b1394665e8aa6840b (patch)
treeec94354a9ccb2f09e77e3a2381b52142544d0ee2 /Modules
parente256accd46af74d2695117e62361fe7ae9dfdfe3 (diff)
downloadcpython-e66987e626cfce8292c39d5b1394665e8aa6840b.zip
cpython-e66987e626cfce8292c39d5b1394665e8aa6840b.tar.gz
cpython-e66987e626cfce8292c39d5b1394665e8aa6840b.tar.bz2
os.urandom() now blocks on Linux
Issue #27776: The os.urandom() function does now block on Linux 3.17 and newer until the system urandom entropy pool is initialized to increase the security. This change is part of the PEP 524.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_randommodule.c56
-rw-r--r--Modules/posixmodule.c3
2 files changed, 47 insertions, 12 deletions
diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c
index 63a060c..1cf57ae 100644
--- a/Modules/_randommodule.c
+++ b/Modules/_randommodule.c
@@ -165,7 +165,7 @@ init_genrand(RandomObject *self, uint32_t s)
/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
-static PyObject *
+static void
init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length)
{
size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */
@@ -190,8 +190,6 @@ init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length)
}
mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
- Py_INCREF(Py_None);
- return Py_None;
}
/*
@@ -199,6 +197,37 @@ init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length)
* Twister download.
*/
+static int
+random_seed_urandom(RandomObject *self)
+{
+ PY_UINT32_T key[N];
+
+ if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) {
+ return -1;
+ }
+ init_by_array(self, key, Py_ARRAY_LENGTH(key));
+ return 0;
+}
+
+static void
+random_seed_time_pid(RandomObject *self)
+{
+ _PyTime_t now;
+ uint32_t key[5];
+
+ now = _PyTime_GetSystemClock();
+ key[0] = (PY_UINT32_T)(now & 0xffffffffU);
+ key[1] = (PY_UINT32_T)(now >> 32);
+
+ key[2] = (PY_UINT32_T)getpid();
+
+ now = _PyTime_GetMonotonicClock();
+ key[3] = (PY_UINT32_T)(now & 0xffffffffU);
+ key[4] = (PY_UINT32_T)(now >> 32);
+
+ init_by_array(self, key, Py_ARRAY_LENGTH(key));
+}
+
static PyObject *
random_seed(RandomObject *self, PyObject *args)
{
@@ -212,14 +241,17 @@ random_seed(RandomObject *self, PyObject *args)
if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg))
return NULL;
- if (arg == NULL || arg == Py_None) {
- time_t now;
+ if (arg == NULL || arg == Py_None) {
+ if (random_seed_urandom(self) >= 0) {
+ PyErr_Clear();
- time(&now);
- init_genrand(self, (uint32_t)now);
- Py_INCREF(Py_None);
- return Py_None;
+ /* Reading system entropy failed, fall back on the worst entropy:
+ use the current time and process identifier. */
+ random_seed_time_pid(self);
+ }
+ Py_RETURN_NONE;
}
+
/* This algorithm relies on the number being unsigned.
* So: if the arg is a PyLong, use its absolute value.
* Otherwise use its hash value, cast to unsigned.
@@ -269,7 +301,11 @@ random_seed(RandomObject *self, PyObject *args)
}
}
#endif
- result = init_by_array(self, key, keyused);
+ init_by_array(self, key, keyused);
+
+ Py_INCREF(Py_None);
+ result = Py_None;
+
Done:
Py_XDECREF(n);
PyMem_Free(key);
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 2dc6d7b..0b9b3f6 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -11168,8 +11168,7 @@ os_urandom_impl(PyObject *module, Py_ssize_t size)
if (bytes == NULL)
return NULL;
- result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
- PyBytes_GET_SIZE(bytes));
+ result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
if (result == -1) {
Py_DECREF(bytes);
return NULL;