summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-19 19:55:27 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-19 20:01:57 +0000
commit3a0460607dbb66094a26231c3fdb23b27305294a (patch)
treea3efd6d977d7b397455464ba3a187b35b0dcce8d
parent2c211d385eb3efdd184895cefb4e242593f8107e (diff)
util/nvmutil: better getrandom safety
err if buf NULL, len -1 also getrandom may return fewer bytes, so loop that too. why can't linux be like bsd? bsd is: arc4random_buf(buf, len); no checks needed. it never errs. Signed-off-by: Leah Rowe <leah@libreboot.org>
-rw-r--r--util/nvmutil/lib/num.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/util/nvmutil/lib/num.c b/util/nvmutil/lib/num.c
index 99503e8c..bbb5a83e 100644
--- a/util/nvmutil/lib/num.c
+++ b/util/nvmutil/lib/num.c
@@ -227,40 +227,44 @@ rlong_next:
#if defined(HAVE_GETRANDOM) || \
defined(HAVE_GETRANDOM_SYSCALL)
int
-fallback_rand_getrandom(void *buf, size_t len)
+fallback_rand_getrandom(void *buf, unsigned long len)
{
- ssize_t rval = -1;
+ unsigned long off = 0;
+ long rval = -1;
- /* keep strict compiler
- * happy if unused
- */
- (void)rval;
- (void)buf;
- (void)len;
+ if (!len)
+ return -1;
-#if defined(HAVE_GETRANDOM)
- do {
- rval = getrandom(buf, len, 0);
- } while (rval < 0 && errno == EINTR);
+ if (buf == NULL)
+ return -1;
-#elif defined(HAVE_GETRANDOM_SYSCALL)
- do {
- rval = syscall(SYS_getrandom, buf, len, 0);
- } while (rval < 0 && errno == EINTR);
+#if defined(HAVE_GETRANDOM) || \
+ defined(HAVE_GETRANDOM_SYSCALL)
-#else
- return -1;
+ while (off < len) {
+
+#if defined(HAVE_GETRANDOM)
+ rval = (long)getrandom((char *)buf + off, len - off, 0);
+#elif defined(HAVE_GETRANDOM_SYSCALL)
+ rval = (long)syscall(SYS_getrandom,
+ (char *)buf + off, len - off, 0);
#endif
-#if defined(HAVE_GETRANDOM) || \
- defined(HAVE_GETRANDOM_SYSCALL)
+ if (rval < 0) {
+ if (errno == EINTR)
+ continue;
+
+ return -1; /* unsupported by kernel */
+ }
- if (rval == (ssize_t)len) {
- return 0;
+ off += (unsigned long)rval;
}
- if (rval < 0 && errno == ENOSYS)
- return -1; /* not supported by kernel */
+ return 0;
+
+#else
+ (void)buf;
+ (void)len;
return -1;
#endif