seedrng: explain why we need locking and fsync'ing
Also, do not test for locking errors: on Linux, they do not happen. function old new delta .rodata 104900 104878 -22 seedrng_main 1022 994 -28 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
0bca489b24
commit
d5bd2e57a7
@ -190,9 +190,17 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
|
|||||||
if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST)
|
if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST)
|
||||||
bb_perror_msg_and_die("can't create directory '%s'", seed_dir);
|
bb_perror_msg_and_die("can't create directory '%s'", seed_dir);
|
||||||
dfd = xopen(seed_dir, O_DIRECTORY | O_RDONLY);
|
dfd = xopen(seed_dir, O_DIRECTORY | O_RDONLY);
|
||||||
if (flock(dfd, LOCK_EX) < 0)
|
|
||||||
bb_perror_msg_and_die("can't lock seed directory");
|
|
||||||
xfchdir(dfd);
|
xfchdir(dfd);
|
||||||
|
/* Concurrent runs of this tool might feed the same data to RNG twice.
|
||||||
|
* Avoid concurrent runs by taking a blocking lock on the directory.
|
||||||
|
* Not checking for errors. Looking at manpage,
|
||||||
|
* ENOLCK "The kernel ran out of memory for allocating lock records"
|
||||||
|
* seems to be the only one which is likely - and if that happens,
|
||||||
|
* machine is OOMing (much worse problem than inability to lock...).
|
||||||
|
* Also, typically configured Linux machines do not fail GFP_KERNEL
|
||||||
|
* allocations (they trigger memory reclaim instead).
|
||||||
|
*/
|
||||||
|
flock(dfd, LOCK_EX); /* would block while another copy runs */
|
||||||
|
|
||||||
sha256_begin(&hash);
|
sha256_begin(&hash);
|
||||||
sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25);
|
sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25);
|
||||||
@ -204,7 +212,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
|
|||||||
for (int i = 1; i < 3; ++i) {
|
for (int i = 1; i < 3; ++i) {
|
||||||
seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME,
|
seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME,
|
||||||
dfd,
|
dfd,
|
||||||
i == 1 ? false : !skip_credit,
|
/* credit? */ i == 1 ? false : !skip_credit,
|
||||||
&hash);
|
&hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,11 +226,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
|
|||||||
(unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-");
|
(unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-");
|
||||||
fd = xopen3(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400);
|
fd = xopen3(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400);
|
||||||
xwrite(fd, new_seed, new_seed_len);
|
xwrite(fd, new_seed, new_seed_len);
|
||||||
if (fsync(fd) < 0) {
|
if (new_seed_creditable) {
|
||||||
bb_perror_msg("can't%s seed", " write");
|
/* More paranoia when we create a file which we believe contains
|
||||||
return (1 << 4);
|
* genuine entropy: make sure disk is not full, quota was't esceeded, etc:
|
||||||
}
|
*/
|
||||||
if (new_seed_creditable)
|
if (fsync(fd) < 0)
|
||||||
|
bb_perror_msg_and_die("can't write '%s'", NON_CREDITABLE_SEED_NAME);
|
||||||
xrename(NON_CREDITABLE_SEED_NAME, CREDITABLE_SEED_NAME);
|
xrename(NON_CREDITABLE_SEED_NAME, CREDITABLE_SEED_NAME);
|
||||||
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user