-
Notifications
You must be signed in to change notification settings - Fork 285
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
Don't open /dev/urandom on startup #6077
Conversation
This reverts commit a0176da.
/dev/urandom may not be available. mirage-crypto can use getrandom syscall if needed. This is now fast enough that we don't need the Random based generator: ``` ╭───────────────────────────────────────┬───────────────────────────┬───────────────────────────┬───────────────────────────╮ │name │ major-allocated │ minor-allocated │ monotonic-clock │ ├───────────────────────────────────────┼───────────────────────────┼───────────────────────────┼───────────────────────────┤ │ uuidx creation/Uuidx.make │ 0.0080 mjw/run│ 58.0004 mnw/run│ 375.5079 ns/run│ │ uuidx creation/Uuidx.make_uuid_urnd │ 0.0000 mjw/run│ 19.0059 mnw/run│ 5510.3318 ns/run│ ╰───────────────────────────────────────┴───────────────────────────┴───────────────────────────┴───────────────────────────╯ ``` Using Random would be ~4x faster, but Fortuna is already >10x faster than /dev/urandom and avoids using system calls, except for seeding: ``` │ uuidx creation/Uuidx.make │ 0.0000 mjw/run│ 19.0001 mnw/run│ 95.5587 ns/run│ ``` There is also a newer version of mirage-crypto-rng that can avoid the Cstruct and give us the string more directly, which we'll soon upgrade to. Signed-off-by: Edwin Török <[email protected]>
let make_uuid_fast () = with_non_csprng_state Uuidm.v4_gen | ||
let fd = Unix.openfile dev [Unix.O_RDONLY] 0o640 in | ||
let finally body_f clean_f = | ||
try |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't take finally from a library or use Fun.protect
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a reformat.
The code works, but I can't find any guarantees that I'll need to go with a different approach. |
… reduce number of syscalls (#6085) This is an alternative to #6077 2 recent optimizations have changed the Uuidx module to open /dev/urandom once on startup, instead of every time a value was requested. However 'networkd_db' runs in the installer environment, inside a chroot where /dev/urandom is not available. Open /dev/urandom on first use instead. Simplify the code and use a single implementation for both fast and secure urandom generation: * use a mutex to protect accesses to global urandom state * use an input channel, rather than a Unix file descriptor, this allows us to read many bytes in one go, and then generate multiple random numbers without having to make syscalls that often (syscalls are slow in this case because they require releasing the runtime mutex, which gives another thread the opportunity to run for 50ms). Fixes: a0176da ("CP-49135: open /dev/urandom just once") Fixes: a2d9fbe ("IH-577 Implement v7 UUID generation") Fixes: 6635a00 ("CP-49136: Introduce PRNG for generating non-secret UUIDs") This is slightly slower than before, but still fast enough: ``` │ uuidx creation/Uuidx.make │ 0.0004 mjw/run│ 16.0001 mnw/run│ 105.8801 ns/run│ │ uuidx creation/Uuidx.make_uuid_urnd │ 0.0004 mjw/run│ 16.0001 mnw/run│ 105.1474 ns/run│ ``` Previously this used to take ~88ns, so in fact the difference is barely noticable. Also remove the feature flag: the previous change was feature flagged too, but broke master anyway (I wouldn't have though anything *doesn't* have /dev/urandom available, and didn't feature flag that part, because in general it is not possible to feature flag startup code without races). `networkd_db` now doesn't try to open this anymore: ``` strace -e openat -e open networkd_db open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/librt.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/var/lib/xcp/networkd.db", O_RDONLY) = 3 +++ exited with 0 +++ ```
The host installer run
networkd_db
in a chroot without creating/dev/urandom
there.Removing the dependency on
uuid
(or on uuid generation) would be difficult, because it is closely tied to theRef
type which is used throughout xapi-types/xapi-idl/etc.However we can use Mirage's crypto rng instead of opening /dev/urandom on startup, and this would use the
getrandom
syscall when available instead.This works on Fedora 40, but I haven't tested yet whether it'd work in our much older CentOS 7 Dom0, hence opening as a draft.
Note that reverting the first commit is not enough, because there was also a followup commit that calls
Random.State.make_self_init
on startup, but that commit doesn't revert cleanly.