aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2022-04-20 15:34:20 +0200
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2022-04-20 15:43:00 +0200
commit398bb3861aa39ae6d3ada7bb54698653b4de370b (patch)
tree17e05f9c94cc460c264491ca6746ea222a6ef072
parent3c60711f836b151b8f361098475c3b0cd162dd17 (diff)
downloadbusybox-w32-398bb3861aa39ae6d3ada7bb54698653b4de370b.tar.gz
busybox-w32-398bb3861aa39ae6d3ada7bb54698653b4de370b.tar.bz2
busybox-w32-398bb3861aa39ae6d3ada7bb54698653b4de370b.zip
seedrng: further reduce size
- Remove all games with errno to further reduce code size. - Combine error messages that don't benefit from being separated. - Lock directory fd instead of separate file. function old new delta static.longopts 38 26 -12 seed_from_file_if_exists 426 413 -13 packed_usage 34519 34480 -39 .rodata 108484 108407 -77 seedrng_main 1088 1000 -88 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/5 up/down: 0/-229) Total: -229 bytes text data bss dec hex filename 976208 4227 1816 982251 efceb busybox_old 975979 4227 1816 982022 efc06 busybox_unstripped Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
-rw-r--r--util-linux/seedrng.c77
1 files changed, 22 insertions, 55 deletions
diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c
index 53be5048a..bc6ae5cb4 100644
--- a/util-linux/seedrng.c
+++ b/util-linux/seedrng.c
@@ -21,7 +21,7 @@
21 */ 21 */
22 22
23//config:config SEEDRNG 23//config:config SEEDRNG
24//config: bool "seedrng (2.4 kb)" 24//config: bool "seedrng (2.1 kb)"
25//config: default y 25//config: default y
26//config: help 26//config: help
27//config: Seed the kernel RNG from seed files, meant to be called 27//config: Seed the kernel RNG from seed files, meant to be called
@@ -33,12 +33,11 @@
33//kbuild:lib-$(CONFIG_SEEDRNG) += seedrng.o 33//kbuild:lib-$(CONFIG_SEEDRNG) += seedrng.o
34 34
35//usage:#define seedrng_trivial_usage 35//usage:#define seedrng_trivial_usage
36//usage: "[-d SEED_DIRECTORY] [-l LOCK_FILE] [-n]" 36//usage: "[-d SEED_DIRECTORY] [-n]"
37//usage:#define seedrng_full_usage "\n\n" 37//usage:#define seedrng_full_usage "\n\n"
38//usage: "Seed the kernel RNG from seed files." 38//usage: "Seed the kernel RNG from seed files."
39//usage: "\n" 39//usage: "\n"
40//usage: "\n -d, --seed-dir DIR Use seed files from specified directory (default: /var/lib/seedrng)" 40//usage: "\n -d, --seed-dir DIR Use seed files from specified directory (default: /var/lib/seedrng)"
41//usage: "\n -l, --lock-file FILE Use file as exclusive lock (default: /var/run/seedrng.lock)"
42//usage: "\n -n, --skip-credit Skip crediting seeds, even if creditable" 41//usage: "\n -n, --skip-credit Skip crediting seeds, even if creditable"
43 42
44#include "libbb.h" 43#include "libbb.h"
@@ -65,14 +64,7 @@
65#define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ 64#define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */
66#endif 65#endif
67 66
68#if ENABLE_PID_FILE_PATH
69#define PID_FILE_PATH CONFIG_PID_FILE_PATH
70#else
71#define PID_FILE_PATH "/var/run"
72#endif
73
74#define DEFAULT_SEED_DIR "/var/lib/seedrng" 67#define DEFAULT_SEED_DIR "/var/lib/seedrng"
75#define DEFAULT_LOCK_FILE PID_FILE_PATH "/seedrng.lock"
76#define CREDITABLE_SEED_NAME "seed.credit" 68#define CREDITABLE_SEED_NAME "seed.credit"
77#define NON_CREDITABLE_SEED_NAME "seed.no-credit" 69#define NON_CREDITABLE_SEED_NAME "seed.no-credit"
78 70
@@ -116,8 +108,6 @@ static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable)
116 return 0; 108 return 0;
117 if (open_read_close("/dev/urandom", seed, len) == (ssize_t)len) 109 if (open_read_close("/dev/urandom", seed, len) == (ssize_t)len)
118 return 0; 110 return 0;
119 if (!errno)
120 errno = EIO;
121 return -1; 111 return -1;
122} 112}
123 113
@@ -155,34 +145,29 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit,
155{ 145{
156 uint8_t seed[MAX_SEED_LEN]; 146 uint8_t seed[MAX_SEED_LEN];
157 ssize_t seed_len; 147 ssize_t seed_len;
158 int ret = 0;
159 148
160 seed_len = open_read_close(filename, seed, sizeof(seed)); 149 seed_len = open_read_close(filename, seed, sizeof(seed));
161 if (seed_len < 0) { 150 if (seed_len < 0) {
162 if (errno != ENOENT) { 151 if (errno == ENOENT)
163 ret = -errno; 152 return 0;
164 bb_simple_perror_msg("unable to read seed file"); 153 bb_simple_perror_msg("unable to read seed file");
165 } 154 return -1;
166 goto out;
167 } 155 }
168 if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { 156 if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) {
169 ret = -errno;
170 bb_simple_perror_msg("unable to remove seed after reading, so not seeding"); 157 bb_simple_perror_msg("unable to remove seed after reading, so not seeding");
171 goto out; 158 return -1;
172 } 159 } else if (!seed_len)
173 if (!seed_len) 160 return 0;
174 goto out;
175 161
176 sha256_hash(hash, &seed_len, sizeof(seed_len)); 162 sha256_hash(hash, &seed_len, sizeof(seed_len));
177 sha256_hash(hash, seed, seed_len); 163 sha256_hash(hash, seed, seed_len);
178 164
179 printf("Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without"); 165 printf("Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without");
180 ret = seed_rng(seed, seed_len, credit); 166 if (seed_rng(seed, seed_len, credit) < 0) {
181 if (ret < 0)
182 bb_simple_perror_msg("unable to seed"); 167 bb_simple_perror_msg("unable to seed");
183out: 168 return -1;
184 errno = -ret; 169 }
185 return ret ? -1 : 0; 170 return 0;
186} 171}
187 172
188int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; 173int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE;
@@ -190,8 +175,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
190{ 175{
191 static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix"; 176 static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix";
192 static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure"; 177 static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure";
193 char *seed_dir, *lock_file, *creditable_seed, *non_creditable_seed; 178 char *seed_dir, *creditable_seed, *non_creditable_seed;
194 int ret, fd = -1, dfd = -1, lock, program_ret = 0; 179 int ret, fd = -1, dfd = -1, program_ret = 0;
195 uint8_t new_seed[MAX_SEED_LEN]; 180 uint8_t new_seed[MAX_SEED_LEN];
196 size_t new_seed_len; 181 size_t new_seed_len;
197 bool new_seed_creditable; 182 bool new_seed_creditable;
@@ -202,22 +187,18 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
202 int opt; 187 int opt;
203 enum { 188 enum {
204 OPT_d = (1 << 0), 189 OPT_d = (1 << 0),
205 OPT_l = (1 << 1), 190 OPT_n = (1 << 1)
206 OPT_n = (1 << 2)
207 }; 191 };
208#if ENABLE_LONG_OPTS 192#if ENABLE_LONG_OPTS
209 static const char longopts[] ALIGN1 = 193 static const char longopts[] ALIGN1 =
210 "seed-dir\0" Required_argument "d" 194 "seed-dir\0" Required_argument "d"
211 "lock-file\0" Required_argument "l"
212 "skip-credit\0" No_argument "n" 195 "skip-credit\0" No_argument "n"
213 ; 196 ;
214#endif 197#endif
215 198
216 opt = getopt32long(argv, "d:l:n", longopts, &seed_dir, &lock_file); 199 opt = getopt32long(argv, "d:n", longopts, &seed_dir);
217 if (!(opt & OPT_d) || !seed_dir) 200 if (!(opt & OPT_d) || !seed_dir)
218 seed_dir = xstrdup(DEFAULT_SEED_DIR); 201 seed_dir = xstrdup(DEFAULT_SEED_DIR);
219 if (!(opt & OPT_l) || !lock_file)
220 lock_file = xstrdup(DEFAULT_LOCK_FILE);
221 skip_credit = opt & OPT_n; 202 skip_credit = opt & OPT_n;
222 creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); 203 creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME);
223 non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME); 204 non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME);
@@ -229,16 +210,9 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
229 if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) 210 if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST)
230 bb_simple_perror_msg_and_die("unable to create seed directory"); 211 bb_simple_perror_msg_and_die("unable to create seed directory");
231 212
232 lock = open(lock_file, O_WRONLY | O_CREAT, 0000);
233 if (lock < 0 || flock(lock, LOCK_EX) < 0) {
234 bb_simple_perror_msg("unable to open lock file");
235 program_ret = 1;
236 goto out;
237 }
238
239 dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); 213 dfd = open(seed_dir, O_DIRECTORY | O_RDONLY);
240 if (dfd < 0) { 214 if (dfd < 0 || flock(dfd, LOCK_EX) < 0) {
241 bb_simple_perror_msg("unable to open seed directory"); 215 bb_simple_perror_msg("unable to open and lock seed directory");
242 program_ret = 1; 216 program_ret = 1;
243 goto out; 217 goto out;
244 } 218 }
@@ -271,26 +245,19 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[])
271 245
272 printf("Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable"); 246 printf("Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable");
273 fd = open(non_creditable_seed, O_WRONLY | O_CREAT | O_TRUNC, 0400); 247 fd = open(non_creditable_seed, O_WRONLY | O_CREAT | O_TRUNC, 0400);
274 if (fd < 0) { 248 if (fd < 0 || full_write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) {
275 bb_simple_perror_msg("unable to open seed file for writing");
276 program_ret |= 1 << 4;
277 goto out;
278 }
279 if (write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) {
280 bb_simple_perror_msg("unable to write seed file"); 249 bb_simple_perror_msg("unable to write seed file");
281 program_ret |= 1 << 5; 250 program_ret |= 1 << 4;
282 goto out; 251 goto out;
283 } 252 }
284 if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) { 253 if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) {
285 bb_simple_perror_msg("unable to make new seed creditable"); 254 bb_simple_perror_msg("unable to make new seed creditable");
286 program_ret |= 1 << 6; 255 program_ret |= 1 << 5;
287 } 256 }
288out: 257out:
289 if (ENABLE_FEATURE_CLEAN_UP && fd >= 0) 258 if (ENABLE_FEATURE_CLEAN_UP && fd >= 0)
290 close(fd); 259 close(fd);
291 if (ENABLE_FEATURE_CLEAN_UP && dfd >= 0) 260 if (ENABLE_FEATURE_CLEAN_UP && dfd >= 0)
292 close(dfd); 261 close(dfd);
293 if (ENABLE_FEATURE_CLEAN_UP && lock >= 0)
294 close(lock);
295 return program_ret; 262 return program_ret;
296} 263}