Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inject /boot/entropy in VM images built for CI #31

Merged
merged 1 commit into from
Apr 16, 2019

Conversation

cemeyer
Copy link
Member

@cemeyer cemeyer commented Apr 15, 2019

Otherwise, random is unlikely to be available early without a fast random
source.

Reported by: Gerald Aryeetey (GeraldNDA @ Github)

Otherwise, random is unlikely to be available early without a fast random
source.

Reported by:	Gerald Aryeetey (GeraldNDA @ Github)
@cemeyer
Copy link
Member Author

cemeyer commented Apr 15, 2019

This change is untested; I don't have the same environment CI runs in.

cemeyer referenced this pull request in freebsd/freebsd-src Apr 15, 2019
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
GeraldNDA added a commit to GeraldNDA/freebsd-ci that referenced this pull request Apr 15, 2019
- Applies freebsd/freebsd-ci pull freebsd#31 by @cem
@lwhsu
Copy link
Member

lwhsu commented Apr 16, 2019

I am going to merge this first for not blocking other tests. We're running tests in bhyve and qemu so there isn't read-only media issue and I'd like to have these images as close to the release images as possible. We should have a more formal way to doing this, like what suggested in freebsd/freebsd-src@654aeb5 .

@lwhsu lwhsu merged commit 8dda9f3 into freebsd:master Apr 16, 2019
@cemeyer
Copy link
Member Author

cemeyer commented Apr 16, 2019

Sure, this might not be the final solution — but it helps.

The normal installer (bsdinstall) populates this file itself. When VM images are created with makefs, we're sometimes missing this step.

Thanks!

@lwhsu
Copy link
Member

lwhsu commented Apr 16, 2019

RISC-V still panics after applying this. While I'm working on this, @cemeyer , can you also help us? The test step is available at: https://wiki.freebsd.org/riscv

@cemeyer
Copy link
Member Author

cemeyer commented Apr 16, 2019

@lwhsu Is it possible to inject /boot/entropy into MFS image that RISCV loads initially? I'm sort of unfamiliar with all of the scripts and images used here. @emaste proposed a patch that:

  1. Adds an API for consumers to detect seeded or unseeded state without the inconvenience and overhead of invoking sys_getrandom(GRND_NONBLOCK);
  2. Uses that API in __stack_chk_init
  3. Adds a tunable used in __stack_chk_init which specifies whether to panic or LOUDLY WARN that the stack guards are non-random;
  4. CI images might just set that tunable, at least for now?

I don't know if it is possible to re-seed the __stack_chk guards later in boot when the device is seeded. It seems difficult, like you would have to walk all stacks and rewrite cookies :-( .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants