STINNER Victor added the comment:

"Hmm. Why does os.urandom(), which should explicitly not block, use a blocking 
getrandom() function? This is quite unexpected on Linux."

I modified os.getrandom() in the issue #22181 to use the new getrandom() 
syscall of Linux 3.17. The syscall blocks until the Linux kernel entropy pool 
is *initialized* with enough entropy. In a healthy system, it must never occur.

To be clear: you get read 10 MB (or 1 GB or more) of random data using 
os.urandom() even if the entropy pool is empty. You can test:

* In a terminal 1, run "dd if=/dev/random of=random" to ensure that the entropy 
pool is empty
* In a terminal 2, run "while true; do cat 
/proc/sys/kernel/random/entropy_avail; sleep 1; done" to see that entropy pool 
is empty (or very low, like less 100 bytes)
* In a terminal 3, get a lot of random data using os.urandom(): ./python -c 
'import os; x=os.urandom(1024*1024*10)'

=> it works, you *can* get 10 MB of random data even if the kernel entropy pool 
is empty.

Reminder: getrandom() is used to avoid a file descriptor which caused various 
issues (see issue #22181 for more information).

Ok, now this issue. The lack of entropy is a known problem in virtual machine. 
It's common that SSH, HTTPS, or other operations block because because of the 
lack of entropy. On bare metal, the Linux entropy pool is feeded by physical 
events like interruptions, keyboard strokes, mouse moves, etc. On a virtual 
machine, there is *no* source of entropy.

The problem is not only known but also solved, at least for qemu: you must 
attach a virtio-rng device to your virtual machine. See for example 
https://fedoraproject.org/wiki/Features/Virtio_RNG The VM can now reads fresh 
and good quality entropy from the host.

To come back to Python: getrandom() syscall only blocks until the entropy pool 
is *initialized* with enough entropy.

The getrandom() syscall has a GRND_NONBLOCK to fail with EAGAIN if reading from 
/dev/random (not /dev/urandom) would block because the entropy pool has not 
enough entropy:
http://man7.org/linux/man-pages/man2/getrandom.2.html

IMHO it's a deliberate choice to block in getrandom() when reading /dev/urandom 
while the entropy pool is not initialized with enough entropy yet.

Ok, now the question is: should python do nothing to support VM badly 
configured (with no real source of entropy)?

It looks like the obvious change is to not use getrandom() but revert code to 
use a file descriptor and read from /dev/urandom. We will get bad entropy, but 
Python will be able to start.

I am not excited by this idea. The os.urandom() private file descriptor caused 
other kinds of issues and bad quality entropy is also an issue.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue26839>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to