On 2017-09-26 17:47, Laurent Bercot wrote: > >> On a modern linux system, s6-rc-update ends up calling getrandom(2) via >> the random_sauniquename() library function. But on embedded systems, and >> especially during early initialization, that is likely to block, which >> means that the entire boot process hangs. > > Yes. That's a feature. You *want* random byte generation to block > until the entropy pool is filled up, else it can lead to security > issues.
TYVM, I'm well aware of the reason getrandom(2) was introduced, and I _do_ want (hope) that whatever utility programs I use that rely on cryptographically strong random numbers (ssh-keygen and whatnot) have been updated to use that (and thus block until they can get such strong random numbers) when available. s6-rc-update does not have any use for cryptographically strong random numbers. >> No, writing 160 bytes of crap to /dev/urandom as random_init does makes >> no difference; it does not in any way "speed up /dev/urandom >> initialization". > > Indeed it doesn't, unfortunately. The point isn't to speed it up, > it's to shuffle the seed a bit more. src/librandom/random_makeseed.c says that that's precisely the point; I was quoting verbatim. 11 Certainly not cryptographically secure or 100% unpredictable, 12 but we're only using this to speed up /dev/urandom 13 initialization or to init an internal SURF PRNG. But I'm glad we agree that the random_init voodoo does not, in fact, have any effect on when getrandom(,,0) becomes non-blocking. >> And no, we cannot just make sure the kernel's random number generator is >> fully initialized before calling s6-rc-update, as s6-rc-update may very >> well be the one that starts the service(s) that eventually ensures this >> initialization (e.g., all the network-facing services). > > And that's what I don't understand. Why are you calling s6-rc-update > as part of your boot process? s6-rc-update is designed for live > service database replacement; at boot time, you don't have anything > to replace. Isn't s6-rc-init + s6-rc enough for your booting > procedure? No, it's not. Roughly, the setup consists of a read-only rootfs (squashfs, so really readonly), with a set of predefined services. As part of the first s6-rc-init + s6-rc, a data partition is mounted, and from the data located there, an additional set of services and/or dependencies are generated, and only when that new service database is compiled do we know precisely which services we need to be up at the end of the init phase. > As an aside, you cannot rely on network-facing services to fill up your > entropy pool. Network-facing services typically use cryptography, and > that is exactly the case where you _need_ a full entropy pool first > and working around it is a very bad idea. Yeah, slightly bad example, but the point is that until the system is fully initialized, which includes ifup'ing some set of ethernet interfaces, talking to some sensors, etc., we don't have a lot of sources of entropy. Even _when_ the board is fully up, it takes up to 30 seconds before the 'random: nonblocking pool is initialized' message appears. Neither the end users, developers, PMs nor the hardware watchdog will tolerate a boot time of upwards of 30 seconds. It's a sad fact, but nevertheless a fact, that many embedded systems out there simply do not have a lot of sources of entropy, so relying on getrandom(,,0) not blocking for too long is simply wrong on such systems. >> In general, none of the infrastructure utilities (skaware or otherwise) >> involved in the boot process can be allowed to make a possibly-blocking >> getrandom() call. > > I agree. That is the reason why why s6-ftrigrd hardcodes the SURF PRNG > for its temporary pipe name generation: > > https://git.skarnet.org/cgi-bin/cgit.cgi/s6/tree/src/libs6/ftrig1_make.c > > I don't like to do this any more than is strictly necessary, because > I don't want to have to wonder about the predictability of the names; > if a program isn't part of the early boot process and has no reason > to be run before the entropy pool fills up, I'd rather rely on randomness > given by the machine. Good, secure randomness. But this part I don't understand. Why do you insist on using your own homebrewed scheme (which will only ever try one - albeit I agree in practice guaranteed to be universally unique - name), when perfectly sane and safe standard functions exist that do the same? I mean, what is the security issue you see with using mkstemp/mkdtemp? What can an attacker possibly do by guessing the name before-hand that he could not do by learning it with readdir() afterwards? You really don't need good, secure randomness for generating a guaranteed-to-be-owned-by-you file/dir. Yes, it's a pity that mkfifotemp and mksymlinktemp do not exist; but it's really not hard to implement them in a way that avoids relying on true random numbers. > I'm open to being convinced that s6-rc-update has a legit reason to be > run before the entropy pool fills up, but that's really not how I see > things; so please elaborate on why your setup is the way it is. I don't understand how you can have a whitelist of programs that (paraphrasing) "may be part of the early boot process and thus may have a reason to run before the entropy pool fills up" - at least, I haven't seen any notice in any skaware documentation that says "don't call this during your init procedure - may effectively deadlock the machine". How should the user know which s6-programs can be used and which cannot? Rasmus -- Rasmus Villemoes Software Developer Prevas A/S Hedeager 1 DK-8200 Aarhus N +45 51210274 rasmus.villem...@prevas.dk www.prevas.dk