mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-17 18:34:57 +02:00
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:
+29
-25
@@ -227,40 +227,44 @@ rlong_next:
|
|||||||
#if defined(HAVE_GETRANDOM) || \
|
#if defined(HAVE_GETRANDOM) || \
|
||||||
defined(HAVE_GETRANDOM_SYSCALL)
|
defined(HAVE_GETRANDOM_SYSCALL)
|
||||||
int
|
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
|
if (!len)
|
||||||
* happy if unused
|
return -1;
|
||||||
*/
|
|
||||||
(void)rval;
|
|
||||||
(void)buf;
|
|
||||||
(void)len;
|
|
||||||
|
|
||||||
#if defined(HAVE_GETRANDOM)
|
if (buf == NULL)
|
||||||
do {
|
return -1;
|
||||||
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
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_GETRANDOM) || \
|
#if defined(HAVE_GETRANDOM) || \
|
||||||
defined(HAVE_GETRANDOM_SYSCALL)
|
defined(HAVE_GETRANDOM_SYSCALL)
|
||||||
|
|
||||||
if (rval == (ssize_t)len) {
|
while (off < len) {
|
||||||
return 0;
|
|
||||||
|
#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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
off += (unsigned long)rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rval < 0 && errno == ENOSYS)
|
return 0;
|
||||||
return -1; /* not supported by kernel */
|
|
||||||
|
#else
|
||||||
|
(void)buf;
|
||||||
|
(void)len;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user