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>
This commit is contained in:
Leah Rowe
2026-03-19 19:55:27 +00:00
parent 2c211d385e
commit 3a0460607d

View File

@@ -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 defined(HAVE_GETRANDOM)
do {
rval = getrandom(buf, len, 0);
} while (rval < 0 && errno == EINTR);
#elif defined(HAVE_GETRANDOM_SYSCALL)
do {
rval = syscall(SYS_getrandom, buf, len, 0);
} while (rval < 0 && errno == EINTR);
#else
if (!len)
return -1;
if (buf == NULL)
return -1;
#endif
#if defined(HAVE_GETRANDOM) || \
defined(HAVE_GETRANDOM_SYSCALL)
if (rval == (ssize_t)len) {
return 0;
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 (rval < 0) {
if (errno == EINTR)
continue;
return -1; /* unsupported by kernel */
}
if (rval < 0 && errno == ENOSYS)
return -1; /* not supported by kernel */
off += (unsigned long)rval;
}
return 0;
#else
(void)buf;
(void)len;
return -1;
#endif