summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-06-21 12:44:13 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-06-29 08:32:59 +0200
commitbe419a9e4cac9428c432d8d7907778d31c12d409 (patch)
tree455928f0f21ed972bcd111d26f01fddd9e3d42ea /src
parent64792da0de8724bb85e9e3cf114c452995c24140 (diff)
downloadouroboros-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.c18
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;