diff options
| author | Hauke Mehrtens | 2026-04-12 22:20:23 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-05-23 00:47:39 +0000 |
| commit | 4ca0b141e9a72a8a87feff3aa6f3ae57a9827177 (patch) | |
| tree | 9dfa91c9d450214585f0b71623b7a9ef3e33e6d2 | |
| parent | 43051ca73aec19c53d20e17e0e37a8ebd7d52d56 (diff) | |
| download | ubus-4ca0b141e9a72a8a87feff3aa6f3ae57a9827177.tar.gz | |
ubusd_id: use getrandom(2) unconditionally on Linux
getrandom() avoids opening a file descriptor, works before /dev/urandom
is accessible (e.g. early boot inside a container), and blocks until
the kernel entropy pool is initialised, making it safer than reading
from /dev/urandom directly.
getrandom() is available since glibc 2.25 and musl 1.1.20. On Linux
call it from <sys/random.h> directly. Non-Linux platforms continue to
use the /dev/urandom fd path unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Link: https://github.com/openwrt/ubus/pull/20
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
| -rw-r--r-- | ubusd_id.c | 31 |
1 files changed, 22 insertions, 9 deletions
@@ -15,12 +15,33 @@ #include <stdlib.h> #include <unistd.h> #include <fcntl.h> +#ifdef __linux__ +#include <sys/random.h> +#endif #include <libubox/avl-cmp.h> #include "ubusmsg.h" #include "ubusd_id.h" +#ifndef __linux__ static int random_fd = -1; +#endif + +static ssize_t read_random(void *buf, size_t len) +{ +#ifdef __linux__ + return getrandom(buf, len, 0); +#else + if (random_fd < 0) { + random_fd = open("/dev/urandom", O_RDONLY); + if (random_fd < 0) { + perror("open /dev/urandom"); + return -1; + } + } + return read(random_fd, buf, len); +#endif +} static int ubus_cmp_id(const void *k1, const void *k2, void *ptr) { @@ -39,14 +60,6 @@ void ubus_init_string_tree(struct avl_tree *tree, bool dup) void ubus_init_id_tree(struct avl_tree *tree) { - if (random_fd < 0) { - random_fd = open("/dev/urandom", O_RDONLY); - if (random_fd < 0) { - perror("open"); - exit(1); - } - } - avl_init(tree, ubus_cmp_id, false, NULL); } @@ -59,7 +72,7 @@ bool ubus_alloc_id(struct avl_tree *tree, struct ubus_id *id, uint32_t val) } do { - if (read(random_fd, &id->id, sizeof(id->id)) != sizeof(id->id)) + if (read_random(&id->id, sizeof(id->id)) != sizeof(id->id)) return false; if (id->id < UBUS_SYSTEM_OBJECT_MAX) |