You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PEP 475: os.urandom() doesn't handle EINTR correctly #67895
dev_urandom_python() retries read() if it fails with EINTR, but Python signal handlers are not called: PyErr_CheckSignals() is not called. It's important be able to interrupt a function by a signal, especially if it's blocking.
We need maybe a new _Py_read() function which would retry on EINTR. The code can be based on posix_read(). For open(), there is already _Py_open() which retries on EINTR (since the changeset ed25e945cdc2, issue bpo-23694). It can be useful for FileIO.read().
dev_urandom_noraise() retries on EINTR without calling PyErr_CheckSignals(). It may be acceptable since this function is only called by _PyRandom_Init() at an early stage of Python initialization. Or maybe EINTR should call Py_FatalError()?
On Linux 3.18 (Fedora 21 with kernel 3.18.7-200.fc21.x86_64), reading 1 GB from /dev/urandom or getrandom() returns 0x1ffffff bytes (32 MB). It's not an issue, os.urandom() continues to read until it gets enough data.
I tried to interrupt os.urandom() on Python 3.4 (read) and Python 3.5 (getrandom): reading from /dev/urandom using a file descriptor or getrandom() have the same behaviour, none fail with EINTR. I checked syscalls using strace.
It looks like getrandom() only fails with EINTR when flags=GRND_RANDOM. So this issue is maybe more theoric.
Activity
vstinner commentedon Mar 19, 2015
dev_urandom_python() retries read() if it fails with EINTR, but Python signal handlers are not called: PyErr_CheckSignals() is not called. It's important be able to interrupt a function by a signal, especially if it's blocking.
We need maybe a new _Py_read() function which would retry on EINTR. The code can be based on posix_read(). For open(), there is already _Py_open() which retries on EINTR (since the changeset ed25e945cdc2, issue bpo-23694). It can be useful for FileIO.read().
dev_urandom_noraise() retries on EINTR without calling PyErr_CheckSignals(). It may be acceptable since this function is only called by _PyRandom_Init() at an early stage of Python initialization. Or maybe EINTR should call Py_FatalError()?
On Linux 3.18 (Fedora 21 with kernel 3.18.7-200.fc21.x86_64), reading 1 GB from /dev/urandom or getrandom() returns 0x1ffffff bytes (32 MB). It's not an issue, os.urandom() continues to read until it gets enough data.
I tried to interrupt os.urandom() on Python 3.4 (read) and Python 3.5 (getrandom): reading from /dev/urandom using a file descriptor or getrandom() have the same behaviour, none fail with EINTR. I checked syscalls using strace.
It looks like getrandom() only fails with EINTR when flags=GRND_RANDOM. So this issue is maybe more theoric.
vstinner commentedon Mar 19, 2015
random.patch: fix the issue with the new _Py_read() function added by the issue bpo-23708.
python-dev commentedon Mar 19, 2015
New changeset e57b4d464d1c by Victor Stinner in branch 'default':
Issue bpo-23707: On UNIX, os.urandom() now calls the Python signal handler when
https://hg.python.org/cpython/rev/e57b4d464d1c