Re: git: e9c023a47aed - stable/12 - random(4): Block read_random(9) on initial seeding

From: Kyle Evans <kevans_at_freebsd.org>
Date: Sun, 13 Feb 2022 01:27:15 UTC
On Sat, Feb 12, 2022 at 7:22 PM David E. O'Brien <obrien@freebsd.org> wrote:
>
> The branch stable/12 has been updated by obrien:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=e9c023a47aedb678c7fdb470f05cfed8dba2586e
>
> commit e9c023a47aedb678c7fdb470f05cfed8dba2586e
> Author:     Conrad Meyer <cem@FreeBSD.org>
> AuthorDate: 2019-04-15 18:40:36 +0000
> Commit:     David E. O'Brien <obrien@FreeBSD.org>
> CommitDate: 2022-02-13 00:32:39 +0000
>
>     random(4): Block read_random(9) on initial seeding
>
>     read_random() is/was used, mostly without error checking, in a lot of
>     very sensitive places in the kernel -- including seeding the widely used
>     arc4random(9).
>
>     Most uses, especially arc4random(9), should block until the device is seeded
>     rather than proceeding with a bogus or empty seed.  I did not spy any
>     obvious kernel consumers where blocking would be inappropriate (in the
>     sense that lack of entropy would be ok -- I did not investigate locking
>     angle thoroughly).  In many instances, arc4random_buf(9) or that family
>     of APIs would be more appropriate anyway; that work was done in r345865.
>
>     A minor cleanup was made to the implementation of the READ_RANDOM function:
>     instead of using a variable-length array on the stack to temporarily store
>     all full random blocks sufficient to satisfy the requested 'len', only store
>     a single block on the stack.  This has some benefit in terms of reducing
>     stack usage, reducing memcpy overhead and reducing devrandom output leakage
>     via the stack.  Additionally, the stack block is now safely zeroed if it was
>     used.
>
>     One caveat of this change is that the kern.arandom sysctl no longer returns
>     zero bytes immediately if the random device is not seeded.  This means that
>     FreeBSD-specific userspace applications which attempted to handle an
>     unseeded random device may be broken by this change.  If such behavior is
>     needed, it can be replaced by the more portable getrandom(2) GRND_NONBLOCK
>     option.
>
>     On any typical FreeBSD system, entropy is persisted on read/write media and
>     used to seed the random device very early in boot, and blocking is never a
>     problem.
>
>     This change primarily impacts the behavior of /dev/random on embedded
>     systems with read-only media that do not configure "nodevice random".  We
>     toggle the default from 'charge on blindly with no entropy' to 'block
>     indefinitely.'  This default is safer, but may cause frustration.  Embedded
>     system designers using FreeBSD have several options.  The most obvious is to
>     plan to have a small writable NVRAM or NAND to persist entropy, like larger
>     systems.  Early entropy can be fed from any loader, or by writing directly
>     to /dev/random during boot.  Some embedded SoCs now provide a fast hardware
>     entropy source; this would also work for quickly seeding Fortuna.  A 3rd
>     option would be creating an embedded-specific, more simplistic random
>     module, like that designed by DJB in [1] (this design still requires a small
>     rewritable media for forward secrecy).  Finally, the least preferred option
>     might be "nodevice random", although I plan to remove this in a subsequent
>     revision.
>
>     To help developers emulate the behavior of these embedded systems on
>     ordinary workstations, the tunable kern.random.block_seeded_status was
>     added.  When set to 1, it blocks the random device.
>
>     I attempted to document this change in random.4 and random.9 and ran into a
>     bunch of out-of-date or irrelevant or inaccurate content and ended up
>     rototilling those documents more than I intended to.  Sorry.  I think
>     they're in a better state now.
>
>     PR:             230875
>     Reviewed by:    delphij, markm (earlier version)
>     Approved by:    secteam(delphij), devrandom(markm)
>     Relnotes:       yes
>     Differential Revision:  https://reviews.freebsd.org/D19744
>
>     (cherry picked from commit 13774e82285e8d5eb3afeff63760725f747f8581)

fwiw, I think this should have been squashed with an MFC of
3782136ff1fc1e076c939246f199e659d950bad5, which was a follow-up
fix/concession.

Thanks,

Kyle Evans