diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-06-21 12:44:13 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-06-29 08:32:59 +0200 |
| commit | be419a9e4cac9428c432d8d7907778d31c12d409 (patch) | |
| tree | 455928f0f21ed972bcd111d26f01fddd9e3d42ea /src | |
| parent | 64792da0de8724bb85e9e3cf114c452995c24140 (diff) | |
| download | ouroboros-be419a9e4cac9428c432d8d7907778d31c12d409.tar.gz ouroboros-be419a9e4cac9428c432d8d7907778d31c12d409.zip | |
lib: Loop getrandom on short reads and EINTR
The getrandom() function may return fewer bytes than requested or fail
with EINTR. Loop until the buffer is filled, retrying on EINTR,
instead of trusting a single call to fill the buffer completely.
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/random.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/lib/random.c b/src/lib/random.c index 2c9a6c0d..a132f470 100644 --- a/src/lib/random.c +++ b/src/lib/random.c @@ -28,6 +28,8 @@ #include <stdlib.h> #elif defined(HAVE_SYS_RANDOM) #include <sys/random.h> +#include <errno.h> +#include <stdint.h> #elif defined(HAVE_LIBGCRYPT) #include <gcrypt.h> #elif defined(HAVE_OPENSSL_RNG) @@ -42,7 +44,21 @@ int random_buffer(void * buf, arc4random_buf(buf, len); return 0; #elif defined(HAVE_SYS_RANDOM) - return getrandom(buf, len, GRND_NONBLOCK); + size_t off = 0; + ssize_t ret; + + while (off < len) { + ret = getrandom((uint8_t *) buf + off, len - off, + GRND_NONBLOCK); + if (ret < 0) { + if (errno == EINTR) + continue; + return -1; + } + off += (size_t) ret; + } + + return 0; #elif defined(HAVE_LIBGCRYPT) gcry_randomize(buf, len, GCRY_STRONG_RANDOM); return 0; |
