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>
This commit is contained in:
Denys Vlasenko 2022-04-30 15:33:28 +02:00
parent 282b61a649
commit 52f3cf7e5f

View File

@ -75,31 +75,38 @@ static size_t determine_optimal_seed_len(void)
return MAX(MIN(poolsize, MAX_SEED_LEN), MIN_SEED_LEN); 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; ssize_t ret;
ret = getrandom(seed, len, GRND_NONBLOCK); ret = getrandom(seed, len, GRND_NONBLOCK);
if (ret == (ssize_t)len) { if (ret == (ssize_t)len) {
*is_creditable = true; return true;
return 0;
} }
if (ret < 0 && errno == ENOSYS) { if (ret < 0 && errno == ENOSYS) {
struct pollfd random_fd = { struct pollfd random_fd = {
.fd = xopen("/dev/random", O_RDONLY), .fd = xopen("/dev/random", O_RDONLY),
.events = POLLIN .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); close(random_fd.fd);
} else { } else {
*is_creditable = false;
if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len) 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; errno = 0;
if (open_read_close("/dev/urandom", seed, len) != (ssize_t)len) if (open_read_close("/dev/urandom", seed, len) != (ssize_t)len)
bb_perror_msg_and_die("can't read '%s'", "/dev/urandom"); 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) 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(); new_seed_len = determine_optimal_seed_len();
if (read_new_seed(new_seed, new_seed_len, &new_seed_creditable) < 0) { new_seed_creditable = read_new_seed(new_seed, new_seed_len);
bb_perror_msg("can't%s seed", " read new");
new_seed_len = SHA256_OUTSIZE;
memset(new_seed, 0, SHA256_OUTSIZE);
program_ret |= 1 << 3;
}
sha256_hash(&hash, &new_seed_len, sizeof(new_seed_len)); sha256_hash(&hash, &new_seed_len, sizeof(new_seed_len));
sha256_hash(&hash, new_seed, new_seed_len); sha256_hash(&hash, new_seed, new_seed_len);
sha256_end(&hash, new_seed + new_seed_len - SHA256_OUTSIZE); 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); 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) { 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"); bb_perror_msg("can't%s seed", " write");