From 331ecc9ae78726433afe941ee24fc1befb15b6ae Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 27 Sep 2022 23:37:05 -0500 Subject: [PATCH] Loop in xgetrandom() when asked to fetch more than 256 bytes at a time. While we're there, eliminate the third argument so the xfunc() always exits when it can't get random data. (Should never happen with syscall, fallback read of /dev node can go away in a couple more years.) --- lib/lib.c | 2 +- lib/password.c | 2 +- lib/portability.c | 17 +++++++++-------- lib/portability.h | 2 +- toys/lsb/mktemp.c | 8 +------- toys/other/mcookie.c | 2 +- toys/other/pwgen.c | 2 +- toys/other/shred.c | 2 +- 8 files changed, 16 insertions(+), 21 deletions(-) diff --git a/lib/lib.c b/lib/lib.c index 33470110..ffa781cb 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -1228,7 +1228,7 @@ int qstrcmp(const void *a, const void *b) void create_uuid(char *uuid) { // "Set all the ... bits to randomly (or pseudo-randomly) chosen values". - xgetrandom(uuid, 16, 0); + xgetrandom(uuid, 16); // "Set the four most significant bits ... of the time_hi_and_version // field to the 4-bit version number [4]". diff --git a/lib/password.c b/lib/password.c index 3497176a..6bea3d70 100644 --- a/lib/password.c +++ b/lib/password.c @@ -23,7 +23,7 @@ int get_salt(char *salt, char *algo) if (al[i].id) s += sprintf(s, "$%c$", '0'+al[i].id); // Read appropriate number of random bytes for salt - xgetrandom(libbuf, ((len*6)+7)/8, 0); + xgetrandom(libbuf, ((len*6)+7)/8); // Grab 6 bit chunks and convert to characters in ./0-9a-zA-Z for (i = 0; i) - if (!getentropy(buf, buflen)) return 1; - if (errno!=ENOSYS && !(flags&WARN_ONLY)) perror_exit("getrandom"); + while (buflen) { + if (getentropy(buf, fd = buflen>256 ? 256 : buflen)) break; + buflen -= fd; + buf += fd; + } + if (!buflen) return; + if (errno!=ENOSYS) perror_exit("getrandom"); #endif - fd = xopen(flags ? "/dev/random" : "/dev/urandom",O_RDONLY|(flags&WARN_ONLY)); - if (fd == -1) return 0; - xreadall(fd, buf, buflen); + xreadall(fd = xopen("/dev/urandom", O_RDONLY), buf, buflen); close(fd); - - return 1; } // Get list of mounted filesystems, including stat and statvfs info. diff --git a/lib/portability.h b/lib/portability.h index 4de547a3..9dd14c0c 100644 --- a/lib/portability.h +++ b/lib/portability.h @@ -350,7 +350,7 @@ extern CODE prioritynames[], facilitynames[]; #if __has_include () #include #endif -int xgetrandom(void *buf, unsigned len, unsigned flags); +void xgetrandom(void *buf, unsigned len); // Android's bionic libc doesn't have confstr. #ifdef __BIONIC__ diff --git a/toys/lsb/mktemp.c b/toys/lsb/mktemp.c index 0986b4fd..d449878a 100644 --- a/toys/lsb/mktemp.c +++ b/toys/lsb/mktemp.c @@ -62,14 +62,8 @@ void mktemp_main(void) long long rr; char *s = template+len; - // Fall back to random-ish if xgetrandom fails. - if (!xgetrandom(&rr, sizeof(rr), WARN_ONLY)) { - struct timespec ts; - - clock_gettime(CLOCK_REALTIME, &ts); - rr = ts.tv_nsec*65537+(long)template+getpid()+(long)&template; - } // Replace X with 64 chars from posix portable character set (all but "_"). + xgetrandom(&rr, sizeof(rr)); while (--s>template) { if (*s != 'X') break; *s = '-'+(rr&63); diff --git a/toys/other/mcookie.c b/toys/other/mcookie.c index fb83f5e3..813b74b5 100644 --- a/toys/other/mcookie.c +++ b/toys/other/mcookie.c @@ -29,7 +29,7 @@ void mcookie_main(void) long long *ll = (void *)toybuf; if (FLAG(V)) return (void)puts("mcookie from toybox"); - xgetrandom(toybuf, 16, 0); + xgetrandom(toybuf, 16); if (FLAG(v)) fputs("Got 16 bytes from xgetrandom()\n", stderr); xprintf("%016llx%06llx\n", ll[0], ll[1]); } diff --git a/toys/other/pwgen.c b/toys/other/pwgen.c index c34daf5a..73627561 100644 --- a/toys/other/pwgen.c +++ b/toys/other/pwgen.c @@ -51,7 +51,7 @@ void pwgen_main(void) for (jj = 0; jj102 less likely if (FLAG(s)) randbuf[rand] = 0; diff --git a/toys/other/shred.c b/toys/other/shred.c index 1932f758..9c13f6bd 100644 --- a/toys/other/shred.c +++ b/toys/other/shred.c @@ -90,7 +90,7 @@ void shred_main(void) throw = sizeof(toybuf); if (FLAG(x) && len-pos < throw) throw = len-pos; - if (iter != TT.n) xgetrandom(toybuf, throw, 0); + if (iter != TT.n) xgetrandom(toybuf, throw); if (throw != writeall(fd, toybuf, throw)) perror_msg_raw(*try); pos += throw; } -- 2.39.2