[git commit] seedrng: simplify read_new_seed() to not have error return

Denys Vlasenko vda.linux at googlemail.com
Sat Apr 30 13:33:28 UTC 2022


commit: https://git.busybox.net/busybox/commit/?id=52f3cf7e5f8c2635ffd456602b74118cf86ec099
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

gcc in fact detects this and does this transformation
when generating code - no object code changes.

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 util-linux/seedrng.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c
index 3f4c5c0c8..5559ba77c 100644
--- a/util-linux/seedrng.c
+++ b/util-linux/seedrng.c
@@ -75,31 +75,38 @@ static size_t determine_optimal_seed_len(void)
 	return MAX(MIN(poolsize, MAX_SEED_LEN), MIN_SEED_LEN);
 }
 
-static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable)
+static bool read_new_seed(uint8_t *seed, size_t len)
 {
+	bool is_creditable;
 	ssize_t ret;
 
 	ret = getrandom(seed, len, GRND_NONBLOCK);
 	if (ret == (ssize_t)len) {
-		*is_creditable = true;
-		return 0;
+		return true;
 	}
 	if (ret < 0 && errno == ENOSYS) {
 		struct pollfd random_fd = {
 			.fd = xopen("/dev/random", O_RDONLY),
 			.events = POLLIN
 		};
-		*is_creditable = poll(&random_fd, 1, 0) == 1;
+		is_creditable = poll(&random_fd, 1, 0) == 1;
+//This is racy. is_creditable can be set to true here, but other process
+//can consume "good" random data from /dev/urandom before we do it below.
 		close(random_fd.fd);
 	} else {
-		*is_creditable = false;
 		if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len)
-			return 0;
+			return false;
+		is_creditable = false;
 	}
+
+	/* Either getrandom() is not implemented, or
+	 * getrandom(GRND_INSECURE) did not give us LEN bytes.
+	 * Fallback to reading /dev/urandom.
+	 */
 	errno = 0;
 	if (open_read_close("/dev/urandom", seed, len) != (ssize_t)len)
 		bb_perror_msg_and_die("can't read '%s'", "/dev/urandom");
-	return 0;
+	return is_creditable;
 }
 
 static void seed_rng(uint8_t *seed, size_t len, bool credit)
@@ -190,17 +197,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
 	}
 
 	new_seed_len = determine_optimal_seed_len();
-	if (read_new_seed(new_seed, new_seed_len, &new_seed_creditable) < 0) {
-		bb_perror_msg("can't%s seed", " read new");
-		new_seed_len = SHA256_OUTSIZE;
-		memset(new_seed, 0, SHA256_OUTSIZE);
-		program_ret |= 1 << 3;
-	}
+	new_seed_creditable = read_new_seed(new_seed, new_seed_len);
 	sha256_hash(&hash, &new_seed_len, sizeof(new_seed_len));
 	sha256_hash(&hash, new_seed, new_seed_len);
 	sha256_end(&hash, new_seed + new_seed_len - SHA256_OUTSIZE);
 
-	printf("Saving %u bits of %screditable seed for next boot\n", (unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-");
+	printf("Saving %u bits of %screditable seed for next boot\n",
+			(unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-");
 	fd = open(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400);
 	if (fd < 0 || full_write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) {
 		bb_perror_msg("can't%s seed", " write");


More information about the busybox-cvs mailing list