summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2022-04-30 15:33:28 +0200
committerDenys Vlasenko2022-04-30 15:33:28 +0200
commit52f3cf7e5f8c2635ffd456602b74118cf86ec099 (patch)
treeda656406faf55eef445a7b2b36e9ff298d98b11b
parent282b61a64921775e5d167df942347a8a3cf984e7 (diff)
downloadbusybox-52f3cf7e5f8c2635ffd456602b74118cf86ec099.zip
busybox-52f3cf7e5f8c2635ffd456602b74118cf86ec099.tar.gz
seedrng: simplify read_new_seed() to not have error return
gcc in fact detects this and does this transformation when generating code - no object code changes. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--util-linux/seedrng.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c
index 3f4c5c0..5559ba7 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");