From 634247ef0cc56ed7f1175f59e3e4bef1045551e5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 5 May 2026 12:56:28 +1000 Subject: [PATCH] os/auth: prefer getrandom() over arc4random_buf() and /dev/urandom Use getrandom() as the preferred source of random data when available, getrandom() works in chroots and containers without the random device node. Note this is a build-time preference, not a runtime preference. Assisted-by: Claude:claude-claude-opus-4-6 Part-of: --- include/meson.build | 1 + os/auth.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/meson.build b/include/meson.build index 3db62aaf4..f766afaeb 100644 --- a/include/meson.build +++ b/include/meson.build @@ -139,6 +139,7 @@ conf_data.set('HAVE_SYS_UTSNAME_H', cc.has_header('sys/utsname.h') ? '1' : false conf_data.set('HAVE_SYS_SYSMACROS_H', cc.has_header('sys/sysmacros.h') ? '1' : false) conf_data.set('HAVE_ARC4RANDOM_BUF', cc.has_function('arc4random_buf', dependencies: libbsd_dep) ? '1' : false) +conf_data.set('HAVE_GETRANDOM', cc.has_function('getrandom', prefix: '#include ') ? '1' : false) conf_data.set('HAVE_BACKTRACE', cc.has_function('backtrace') ? '1' : false) conf_data.set('HAVE_CBRT', cc.has_function('cbrt') ? '1' : false) conf_data.set('HAVE_EPOLL_CREATE1', cc.has_function('epoll_create1') ? '1' : false) diff --git a/os/auth.c b/os/auth.c index 9738ac98d..5a30b5785 100644 --- a/os/auth.c +++ b/os/auth.c @@ -47,6 +47,9 @@ from The Open Group. #include #endif #include /* for arc4random_buf() */ +#ifdef HAVE_GETRANDOM +#include /* for getrandom() */ +#endif struct protocol { unsigned short name_length; @@ -302,7 +305,21 @@ GenerateAuthorization(unsigned name_length, void GenerateRandomData(int len, char *buf) { -#ifdef HAVE_ARC4RANDOM_BUF +#ifdef HAVE_GETRANDOM + ssize_t ret; + int pos = 0; + + while (pos < len) { + ret = getrandom(buf + pos, len - pos, 0); + if (ret <= 0) { + if (ret < 0 && errno == EINTR) + continue; + FatalError("Cannot read random data via getrandom(): %s\n", + strerror(errno)); + } + pos += ret; + } +#elif defined(HAVE_ARC4RANDOM_BUF) arc4random_buf(buf, len); #else int fd;