[Security-sig] RFC: PEP: Make os.urandom() blocking on Linux

Nick Coghlan ncoghlan at gmail.com
Thu Jun 23 14:10:33 EDT 2016


On 23 June 2016 at 10:31, Nick Coghlan <ncoghlan at gmail.com> wrote:
> Reasonable developer experience:
>
> * just keep using os.urandom(), Python will transparently upgrade your
> code to the best non-blocking-in-practice system interface the OS has
> to offer
> * if os.urandom() throws BlockingIOError, you may need to add
> application startup code to wait until the system random number
> generator is ready

Thinking about this some more, I realised applications can implement
the "Wait for system RNG" behaviour even without os.getrandom:

    # Busy loop, given PEP 522's BlockingIOError
    def wait_for_system_rng():
        while True:
            try:
                os.urandom(1)
                break
            except BlockingIOError:
               continue

    # An actual use case for reading /dev/random!
    def wait_for_system_rng():
        try:
            block_on_system_rng = open("/dev/random", "rb")
        except FileNotFoundError:
            return
        with block_on_system_rng:
            block_on_system_rng.read(1)

That second one has the added bonus of doing the right thing even on
older Linux kernels that don't provide the new getrandom() syscall,
creating the following virtuous feedback loop:

1. Start running an existing application/script on Python 3.6 and a
Linux kernel with getrandom()
2. Start getting "BlockingIOError: system random number generator not ready"
3. Add the /dev/random snippet to wait for the system RNG
4. Your code now does the right thing even on older Pythons and Linux versions

Given that realisation, I'm back to thinking "We don't need it" when
it comes to exposing os.getrandom() directly.

Regards,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Security-SIG mailing list