diff options
| author | Hauke Mehrtens | 2026-06-28 12:01:07 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-28 14:46:56 +0000 |
| commit | 24864e7840b3a02a9ef76284a373f6b2f00b8a9b (patch) | |
| tree | 0695b20e11feaba810771d55a598070c2ffd1d65 | |
| parent | 795b32bb96b611493f423666236e9c1e49e0736c (diff) | |
| download | ubus-24864e7840b3a02a9ef76284a373f6b2f00b8a9b.tar.gz | |
Commit 4ca0b141e9a7 ("ubusd_id: use getrandom(2) unconditionally on
Linux") switched ID allocation from non-blocking /dev/urandom reads to
getrandom(buf, len, 0). With flags == 0, getrandom() blocks until the
kernel CRNG is fully seeded.
ubusd's first ID allocation runs inside procd's "ubus" stage, and procd
does not advance past that stage until ubusd is up. urngd, which seeds
the entropy pool quickly, is only started by procd after the "ubus"
stage. On boards whose CRNG seeds slowly (e.g. Rockchip RK3328: NanoPi
R2S / R2S Plus / R4S, Orange Pi R1 Plus LTS) nothing seeds the pool
while ubusd waits, so boot stalls for minutes until slow timer/interrupt
entropy fills it.
ubus IDs only need to be hard to guess, not cryptographically strong,
and were sourced from non-blocking /dev/urandom for years. Use
GRND_INSECURE, which returns bytes immediately without waiting for the
CRNG, restoring the previous early-boot behaviour while keeping the
benefits of getrandom() (no file descriptor, works before /dev/urandom
exists). Define GRND_INSECURE for libc headers predating Linux 5.6.
Fixes: https://github.com/openwrt/ubus/issues/21
Assisted-by: Claude:claude-opus-4-8
Link: https://github.com/openwrt/ubus/pull/24
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
| -rw-r--r-- | ubusd_id.c | 11 |
1 files changed, 10 insertions, 1 deletions
@@ -17,6 +17,10 @@ #include <fcntl.h> #ifdef __linux__ #include <sys/random.h> +/* Added in Linux 5.6; define it in case the libc headers are older. */ +#ifndef GRND_INSECURE +#define GRND_INSECURE 0x0004 +#endif #endif #include <libubox/avl-cmp.h> @@ -30,7 +34,12 @@ static int random_fd = -1; static ssize_t read_random(void *buf, size_t len) { #ifdef __linux__ - return getrandom(buf, len, 0); + /* + * IDs only need to be hard to guess, not crypto-strong. + * GRND_INSECURE returns bytes without blocking on the CRNG, so + * ubusd does not stall boot on boards whose pool seeds late. + */ + return getrandom(buf, len, GRND_INSECURE); #else if (random_fd < 0) { random_fd = open("/dev/urandom", O_RDONLY); |