aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util-linux/seedrng.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c
index a02609a92..c07bf84f7 100644
--- a/util-linux/seedrng.c
+++ b/util-linux/seedrng.c
@@ -190,9 +190,17 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
190 if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) 190 if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST)
191 bb_perror_msg_and_die("can't create directory '%s'", seed_dir); 191 bb_perror_msg_and_die("can't create directory '%s'", seed_dir);
192 dfd = xopen(seed_dir, O_DIRECTORY | O_RDONLY); 192 dfd = xopen(seed_dir, O_DIRECTORY | O_RDONLY);
193 if (flock(dfd, LOCK_EX) < 0)
194 bb_perror_msg_and_die("can't lock seed directory");
195 xfchdir(dfd); 193 xfchdir(dfd);
194 /* Concurrent runs of this tool might feed the same data to RNG twice.
195 * Avoid concurrent runs by taking a blocking lock on the directory.
196 * Not checking for errors. Looking at manpage,
197 * ENOLCK "The kernel ran out of memory for allocating lock records"
198 * seems to be the only one which is likely - and if that happens,
199 * machine is OOMing (much worse problem than inability to lock...).
200 * Also, typically configured Linux machines do not fail GFP_KERNEL
201 * allocations (they trigger memory reclaim instead).
202 */
203 flock(dfd, LOCK_EX); /* would block while another copy runs */
196 204
197 sha256_begin(&hash); 205 sha256_begin(&hash);
198 sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25); 206 sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25);
@@ -204,7 +212,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
204 for (int i = 1; i < 3; ++i) { 212 for (int i = 1; i < 3; ++i) {
205 seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, 213 seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME,
206 dfd, 214 dfd,
207 i == 1 ? false : !skip_credit, 215 /* credit? */ i == 1 ? false : !skip_credit,
208 &hash); 216 &hash);
209 } 217 }
210 218
@@ -218,11 +226,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
218 (unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-"); 226 (unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-");
219 fd = xopen3(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400); 227 fd = xopen3(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400);
220 xwrite(fd, new_seed, new_seed_len); 228 xwrite(fd, new_seed, new_seed_len);
221 if (fsync(fd) < 0) { 229 if (new_seed_creditable) {
222 bb_perror_msg("can't%s seed", " write"); 230 /* More paranoia when we create a file which we believe contains
223 return (1 << 4); 231 * genuine entropy: make sure disk is not full, quota was't esceeded, etc:
224 } 232 */
225 if (new_seed_creditable) 233 if (fsync(fd) < 0)
234 bb_perror_msg_and_die("can't write '%s'", NON_CREDITABLE_SEED_NAME);
226 xrename(NON_CREDITABLE_SEED_NAME, CREDITABLE_SEED_NAME); 235 xrename(NON_CREDITABLE_SEED_NAME, CREDITABLE_SEED_NAME);
236 }
227 return EXIT_SUCCESS; 237 return EXIT_SUCCESS;
228} 238}