From bugzilla at busybox.net Fri Apr 1 09:38:36 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 01 Apr 2022 09:38:36 +0000 Subject: [Bug 14736] New: sendmail used as relay returns error ". failed" Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14736 Bug ID: 14736 Summary: sendmail used as relay returns error ". failed" Product: Busybox Version: 1.32.x Hardware: PC OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: chingis at wodby.com CC: busybox-cvs at busybox.net Target Milestone: --- I'm on Alpine 3.13 with busybox v1.32.1. I use busybox's sendmail as a relay: sendmail_path = /usr/sbin/sendmail -t -i -S opensmtpd:25 since recently it started to give the error "sendmail: . failed" -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Fri Apr 1 14:32:07 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 01 Apr 2022 14:32:07 +0000 Subject: [Bug 14736] sendmail used as relay returns error ". failed" In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14736 chingis at wodby.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #1 from chingis at wodby.com --- ok, it actually works fine, I was confused by the error. After adding more verbosity I saw the actual error which is "sendmail: 550 5.7.1 Delivery not authorized, message refused: Message is not RFC 2822 compliant" -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Sun Apr 10 22:26:27 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sun, 10 Apr 2022 22:26:27 +0000 Subject: [Bug 14241] uudecode doesn't recognise the special decode_pathname /dev/stdout In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14241 --- Comment #10 from Christoph Anton Mitterer --- Just for the records, if someone ever stumbles over this: It seems as if "-" might also be standardised as a "special symbol" (just like the string /dev/stdout is) with the next revision of POSIX. See https://www.austingroupbugs.net/view.php?id=1544 The string "/dev/stdout" would however not be dropped from being required, too. -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Thu Apr 14 15:16:17 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Thu, 14 Apr 2022 15:16:17 +0000 Subject: [Bug 12291] tar command fails when specifying directory to untar if specific thing from directory was added (not the directory itself) In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=12291 --- Comment #3 from Devid Antonio Filoni --- To create a tarball that reproduces the issue you can use the following commands: ~# cd /tmp/ /tmp# mkdir test /tmp# touch test/a /tmp# tar zcvf test.tar.gz test/a test/a /tmp# mkdir test2 /tmp# tar zxvf test.tar.gz -C test2/ test test/a tar: test: not found in archive The tar works fine if it is created with the following command: /tmp# tar zcvf test.tar.gz test test/ test/a In attaching a patch (based on busybox v1.31.1) that seems to fix the issue. -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Thu Apr 14 15:18:44 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Thu, 14 Apr 2022 15:18:44 +0000 Subject: [Bug 12291] tar command fails when specifying directory to untar if specific thing from directory was added (not the directory itself) In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=12291 Devid Antonio Filoni changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |devid.filoni at egluetechnolog | |ies.com --- Comment #4 from Devid Antonio Filoni --- Created attachment 9281 --> https://bugs.busybox.net/attachment.cgi?id=9281&action=edit Patch for busybox 1.31.1 -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Sun Apr 17 17:48:23 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sun, 17 Apr 2022 17:48:23 +0000 Subject: [Bug 14756] New: busybox segfaults when argv[0]==NULL Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14756 Bug ID: 14756 Summary: busybox segfaults when argv[0]==NULL Product: Busybox Version: unspecified Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: logoerthiner1 at 163.com CC: busybox-cvs at busybox.net Target Milestone: --- This is a fairly old bug (feature?) ``` python3 -c "import ctypes;print(ctypes.CDLL('libc.so.6').execve(b'/sbin/busybox',0,0))" ``` This makes busybox segfault. busybox could have a better way to deal with it, for example assume the applet is "" or "busybox" or get the path from `/proc/self/exe`, depending on the case. Even if rejecting argv[0]=NULL is a feature, `exit(1)` should be better than segfault, as segfault is effectively a ub. -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Sun Apr 17 18:06:46 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sun, 17 Apr 2022 18:06:46 +0000 Subject: [Bug 14761] New: commands using SET_PTR_TO_GLOBALS segfaults when compiled with clang 12.0.1 Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14761 Bug ID: 14761 Summary: commands using SET_PTR_TO_GLOBALS segfaults when compiled with clang 12.0.1 Product: Busybox Version: unspecified Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: logoerthiner1 at 163.com CC: busybox-cvs at busybox.net Target Milestone: --- Created attachment 9286 --> https://bugs.busybox.net/attachment.cgi?id=9286&action=edit .config file for reference; mostly defconfig with only tweaks in general config I compiled busybox using clang (12.0.1, default version on alpine 3.15 amd64, make CC=clang STRIP=llvm-strip) on aarch64 architecture, and then run it on aarch64 linux kernel. Some of commands segfaults directly: ``` ~ $ busybox getty Segmentation fault ~ $ busybox vi Segmentation fault ~ $ busybox awk Segmentation fault ~ $ busybox ed Segmentation fault ~ $ busybox diff Segmentation fault ~ $ busybox netstat Segmentation fault ~ $ busybox wget Segmentation fault ~ $ busybox ftpd Segmentation fault ~ $ busybox httpd Segmentation fault ~ $ busybox ntpd ~ $ busybox arping Segmentation fault ``` I suspect SET_PTR_TO_GLOBALS is the culprit, since many commands using SET_PTR_TO_GLOBALS does not work at all. clang 12.0.1 may not respect "unconst" black magic in busybox. -- You are receiving this mail because: You are on the CC list for the bug. From rep.dot.nop at gmail.com Wed Apr 20 13:22:55 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:22:55 +0200 Subject: [git commit] seedrng: use libbb functions Message-ID: <20220420133636.E8F627FB00@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=453857899616acf1c77d0d02a4c2989b2cf5f1eb branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master - Make extensive use of libbb.h functions, which simplify a lot of code and reduce binary size considerably. - Use the already existing PID_FILE_PATH variable. function old new delta seed_from_file_if_exists 697 533 -164 .rodata 108665 108484 -181 seedrng_main 1463 1218 -245 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-590) Total: -590 bytes text data bss dec hex filename 977035 4227 1848 983110 f0046 busybox_old 976445 4227 1848 982520 efdf8 busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 148 ++++++++++++++++++++------------------------------- 1 file changed, 59 insertions(+), 89 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 2950acde0..d82a942aa 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -6,7 +6,7 @@ */ //config:config SEEDRNG -//config: bool "seedrng (3.8 kb)" +//config: bool "seedrng (2.6 kb)" //config: default y //config: help //config: Seed the kernel RNG from seed files, meant to be called @@ -50,53 +50,38 @@ #define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ #endif -#ifndef LOCALSTATEDIR -#define LOCALSTATEDIR "/var/lib" -#endif -#ifndef RUNSTATEDIR -#define RUNSTATEDIR "/var/run" +#if ENABLE_PID_FILE_PATH +#define PID_FILE_PATH CONFIG_PID_FILE_PATH +#else +#define PID_FILE_PATH "/var/run" #endif -#define DEFAULT_SEED_DIR LOCALSTATEDIR "/seedrng" -#define DEFAULT_LOCK_FILE RUNSTATEDIR "/seedrng.lock" +#define DEFAULT_SEED_DIR "/var/lib/seedrng" +#define DEFAULT_LOCK_FILE PID_FILE_PATH "/seedrng.lock" #define CREDITABLE_SEED_NAME "seed.credit" #define NON_CREDITABLE_SEED_NAME "seed.no-credit" static char *seed_dir, *lock_file, *creditable_seed, *non_creditable_seed; enum seedrng_lengths { - MAX_SEED_LEN = 512, - MIN_SEED_LEN = SHA256_OUTSIZE + MIN_SEED_LEN = SHA256_OUTSIZE, + MAX_SEED_LEN = 512 }; -#ifndef DIV_ROUND_UP -#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) -#endif - static size_t determine_optimal_seed_len(void) { - size_t ret = 0; char poolsize_str[11] = { 0 }; - int fd = open("/proc/sys/kernel/random/poolsize", O_RDONLY); - if (fd < 0 || read(fd, poolsize_str, sizeof(poolsize_str) - 1) < 0) { - fprintf(stderr, "WARNING: Unable to determine pool size, falling back to %u bits: %s\n", MIN_SEED_LEN * 8, strerror(errno)); - ret = MIN_SEED_LEN; - } else - ret = DIV_ROUND_UP(strtoul(poolsize_str, NULL, 10), 8); - if (fd >= 0) - close(fd); - if (ret < MIN_SEED_LEN) - ret = MIN_SEED_LEN; - else if (ret > MAX_SEED_LEN) - ret = MAX_SEED_LEN; - return ret; + if (open_read_close("/proc/sys/kernel/random/poolsize", poolsize_str, sizeof(poolsize_str) - 1) < 0) { + bb_perror_msg("unable to determine pool size, falling back to %u bits", MIN_SEED_LEN * 8); + return MIN_SEED_LEN; + } + return MAX(MIN((bb_strtoul(poolsize_str, NULL, 10) + 7) / 8, MAX_SEED_LEN), MIN_SEED_LEN); } static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) { ssize_t ret; - int urandom_fd; *is_creditable = false; ret = getrandom(seed, len, GRND_NONBLOCK); @@ -109,21 +94,16 @@ static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) .events = POLLIN }; if (random_fd.fd < 0) - return -errno; - *is_creditable = poll(&random_fd, 1, 0) == 1; + return -1; + *is_creditable = safe_poll(&random_fd, 1, 0) == 1; close(random_fd.fd); } else if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len) return 0; - urandom_fd = open("/dev/urandom", O_RDONLY); - if (urandom_fd < 0) - return -errno; - ret = read(urandom_fd, seed, len); - if (ret == (ssize_t)len) - ret = 0; - else - ret = -errno ? -errno : -EIO; - close(urandom_fd); - return ret; + if (open_read_close("/dev/urandom", seed, len) == (ssize_t)len) + return 0; + if (!errno) + errno = EIO; + return -1; } static int seed_rng(uint8_t *seed, size_t len, bool credit) @@ -138,69 +118,63 @@ static int seed_rng(uint8_t *seed, size_t len, bool credit) }; int random_fd, ret; - if (len > sizeof(req.buffer)) - return -EFBIG; + if (len > sizeof(req.buffer)) { + errno = EFBIG; + return -1; + } memcpy(req.buffer, seed, len); random_fd = open("/dev/random", O_RDWR); if (random_fd < 0) - return -errno; + return -1; ret = ioctl(random_fd, RNDADDENTROPY, &req); if (ret) ret = -errno ? -errno : -EIO; close(random_fd); - return ret; + errno = -ret; + return ret ? -1 : 0; } static int seed_from_file_if_exists(const char *filename, bool credit, sha256_ctx_t *hash) { uint8_t seed[MAX_SEED_LEN]; ssize_t seed_len; - int fd, dfd, ret = 0; + int dfd = -1, ret = 0; - fd = open(filename, O_RDONLY); - if (fd < 0 && errno == ENOENT) - return 0; - else if (fd < 0) { - ret = -errno; - fprintf(stderr, "ERROR: Unable to open seed file: %s\n", strerror(errno)); - return ret; - } dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); if (dfd < 0) { ret = -errno; - close(fd); - fprintf(stderr, "ERROR: Unable to open seed directory: %s\n", strerror(errno)); - return ret; + bb_simple_perror_msg("unable to open seed directory"); + goto out; } - seed_len = read(fd, seed, sizeof(seed)); + seed_len = open_read_close(filename, seed, sizeof(seed)); if (seed_len < 0) { - ret = -errno; - fprintf(stderr, "ERROR: Unable to read seed file: %s\n", strerror(errno)); - } - close(fd); - if (ret) { - close(dfd); - return ret; + if (errno != ENOENT) { + ret = -errno; + bb_simple_perror_msg("unable to read seed file"); + } + goto out; } if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { ret = -errno; - fprintf(stderr, "ERROR: Unable to remove seed after reading, so not seeding: %s\n", strerror(errno)); + bb_simple_perror_msg("unable to remove seed after reading, so not seeding"); + goto out; } - close(dfd); - if (ret) - return ret; if (!seed_len) - return 0; + goto out; sha256_hash(hash, &seed_len, sizeof(seed_len)); sha256_hash(hash, seed, seed_len); - fprintf(stdout, "Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without"); + printf("Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without"); ret = seed_rng(seed, seed_len, credit); if (ret < 0) - fprintf(stderr, "ERROR: Unable to seed: %s\n", strerror(-ret)); - return ret; + bb_simple_perror_msg("unable to seed"); +out: + if (dfd >= 0) + close(dfd); + errno = -ret; + return ret ? -1 : 0; } int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; @@ -236,14 +210,12 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) if (!(opt & OPT_l) || !lock_file) lock_file = xstrdup(DEFAULT_LOCK_FILE); skip_credit = opt & OPT_n; - creditable_seed = xasprintf("%s/%s", seed_dir, CREDITABLE_SEED_NAME); - non_creditable_seed = xasprintf("%s/%s", seed_dir, NON_CREDITABLE_SEED_NAME); + creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); + non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME); umask(0077); - if (getuid()) { - fprintf(stderr, "ERROR: This program requires root\n"); - return 1; - } + if (getuid()) + bb_simple_error_msg_and_die("this program requires root"); sha256_begin(&hash); sha256_hash(&hash, seedrng_prefix, strlen(seedrng_prefix)); @@ -252,14 +224,12 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) sha256_hash(&hash, &realtime, sizeof(realtime)); sha256_hash(&hash, &boottime, sizeof(boottime)); - if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) { - fprintf(stderr, "ERROR: Unable to create \"%s\" directory: %s\n", seed_dir, strerror(errno)); - return 1; - } + if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) + bb_simple_perror_msg_and_die("unable to create seed directory"); lock = open(lock_file, O_WRONLY | O_CREAT, 0000); if (lock < 0 || flock(lock, LOCK_EX) < 0) { - fprintf(stderr, "ERROR: Unable to open lock file: %s\n", strerror(errno)); + bb_simple_perror_msg("unable to open lock file"); program_ret = 1; goto out; } @@ -274,7 +244,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) new_seed_len = determine_optimal_seed_len(); ret = read_new_seed(new_seed, new_seed_len, &new_seed_creditable); if (ret < 0) { - fprintf(stderr, "ERROR: Unable to read new seed: %s\n", strerror(-ret)); + bb_simple_perror_msg("unable to read new seed"); new_seed_len = SHA256_OUTSIZE; strncpy((char *)new_seed, seedrng_failure, new_seed_len); program_ret |= 1 << 3; @@ -283,20 +253,20 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) sha256_hash(&hash, new_seed, new_seed_len); sha256_end(&hash, new_seed + new_seed_len - SHA256_OUTSIZE); - fprintf(stdout, "Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable"); + printf("Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable"); fd = open(non_creditable_seed, O_WRONLY | O_CREAT | O_TRUNC, 0400); if (fd < 0) { - fprintf(stderr, "ERROR: Unable to open seed file for writing: %s\n", strerror(errno)); + bb_simple_perror_msg("unable to open seed file for writing"); program_ret |= 1 << 4; goto out; } if (write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) { - fprintf(stderr, "ERROR: Unable to write seed file: %s\n", strerror(errno)); + bb_simple_perror_msg("unable to write seed file"); program_ret |= 1 << 5; goto out; } if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) { - fprintf(stderr, "WARNING: Unable to make new seed creditable: %s\n", strerror(errno)); + bb_simple_perror_msg("unable to make new seed creditable"); program_ret |= 1 << 6; } out: From rep.dot.nop at gmail.com Wed Apr 20 13:43:00 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:43:00 +0200 Subject: [git commit] seedrng: use predefined strings where possible Message-ID: <20220420133637.1C64183DAE@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=ce9a345632786d5585044ed71ed4c98c305b918f branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master - Use predefined strings where possible. - Open /dev/random with O_RDONLY for ioctl(). function old new delta seed_from_file_if_exists 413 410 -3 .rodata 108407 108350 -57 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-60) Total: -60 bytes text data bss dec hex filename 975979 4227 1816 982022 efc06 busybox_old 975919 4227 1816 981962 efbca busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index bc6ae5cb4..49b9ab54b 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -79,7 +79,7 @@ static size_t determine_optimal_seed_len(void) unsigned long poolsize; if (open_read_close("/proc/sys/kernel/random/poolsize", poolsize_str, sizeof(poolsize_str) - 1) < 0) { - bb_perror_msg("unable to determine pool size, falling back to %u bits", MIN_SEED_LEN * 8); + bb_perror_msg("unable to determine pool size, assuming %u bits", MIN_SEED_LEN * 8); return MIN_SEED_LEN; } poolsize = (bb_strtoul(poolsize_str, NULL, 10) + 7) / 8; @@ -129,7 +129,7 @@ static int seed_rng(uint8_t *seed, size_t len, bool credit) } memcpy(req.buffer, seed, len); - random_fd = open("/dev/random", O_RDWR); + random_fd = open("/dev/random", O_RDONLY); if (random_fd < 0) return -1; ret = ioctl(random_fd, RNDADDENTROPY, &req); @@ -154,7 +154,7 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, return -1; } if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { - bb_simple_perror_msg("unable to remove seed after reading, so not seeding"); + bb_simple_perror_msg("unable to remove seed, so not seeding"); return -1; } else if (!seed_len) return 0; @@ -205,14 +205,14 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) umask(0077); if (getuid()) - bb_simple_error_msg_and_die("this program requires root"); + bb_simple_error_msg_and_die(bb_msg_you_must_be_root); if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) bb_simple_perror_msg_and_die("unable to create seed directory"); dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); if (dfd < 0 || flock(dfd, LOCK_EX) < 0) { - bb_simple_perror_msg("unable to open and lock seed directory"); + bb_simple_perror_msg("unable to lock seed directory"); program_ret = 1; goto out; } From rep.dot.nop at gmail.com Wed Apr 20 13:43:00 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:43:00 +0200 Subject: [git commit] seedrng: further reduce size Message-ID: <20220420133637.1372F83DAC@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=398bb3861aa39ae6d3ada7bb54698653b4de370b branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master - 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 Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 77 +++++++++++++++------------------------------------- 1 file 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 @@ */ //config:config SEEDRNG -//config: bool "seedrng (2.4 kb)" +//config: bool "seedrng (2.1 kb)" //config: default y //config: help //config: Seed the kernel RNG from seed files, meant to be called @@ -33,12 +33,11 @@ //kbuild:lib-$(CONFIG_SEEDRNG) += seedrng.o //usage:#define seedrng_trivial_usage -//usage: "[-d SEED_DIRECTORY] [-l LOCK_FILE] [-n]" +//usage: "[-d SEED_DIRECTORY] [-n]" //usage:#define seedrng_full_usage "\n\n" //usage: "Seed the kernel RNG from seed files." //usage: "\n" //usage: "\n -d, --seed-dir DIR Use seed files from specified directory (default: /var/lib/seedrng)" -//usage: "\n -l, --lock-file FILE Use file as exclusive lock (default: /var/run/seedrng.lock)" //usage: "\n -n, --skip-credit Skip crediting seeds, even if creditable" #include "libbb.h" @@ -65,14 +64,7 @@ #define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ #endif -#if ENABLE_PID_FILE_PATH -#define PID_FILE_PATH CONFIG_PID_FILE_PATH -#else -#define PID_FILE_PATH "/var/run" -#endif - #define DEFAULT_SEED_DIR "/var/lib/seedrng" -#define DEFAULT_LOCK_FILE PID_FILE_PATH "/seedrng.lock" #define CREDITABLE_SEED_NAME "seed.credit" #define NON_CREDITABLE_SEED_NAME "seed.no-credit" @@ -116,8 +108,6 @@ static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) return 0; if (open_read_close("/dev/urandom", seed, len) == (ssize_t)len) return 0; - if (!errno) - errno = EIO; return -1; } @@ -155,34 +145,29 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, { uint8_t seed[MAX_SEED_LEN]; ssize_t seed_len; - int ret = 0; seed_len = open_read_close(filename, seed, sizeof(seed)); if (seed_len < 0) { - if (errno != ENOENT) { - ret = -errno; - bb_simple_perror_msg("unable to read seed file"); - } - goto out; + if (errno == ENOENT) + return 0; + bb_simple_perror_msg("unable to read seed file"); + return -1; } if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { - ret = -errno; bb_simple_perror_msg("unable to remove seed after reading, so not seeding"); - goto out; - } - if (!seed_len) - goto out; + return -1; + } else if (!seed_len) + return 0; sha256_hash(hash, &seed_len, sizeof(seed_len)); sha256_hash(hash, seed, seed_len); printf("Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without"); - ret = seed_rng(seed, seed_len, credit); - if (ret < 0) + if (seed_rng(seed, seed_len, credit) < 0) { bb_simple_perror_msg("unable to seed"); -out: - errno = -ret; - return ret ? -1 : 0; + return -1; + } + return 0; } int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; @@ -190,8 +175,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix"; static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure"; - char *seed_dir, *lock_file, *creditable_seed, *non_creditable_seed; - int ret, fd = -1, dfd = -1, lock, program_ret = 0; + char *seed_dir, *creditable_seed, *non_creditable_seed; + int ret, fd = -1, dfd = -1, program_ret = 0; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; bool new_seed_creditable; @@ -202,22 +187,18 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) int opt; enum { OPT_d = (1 << 0), - OPT_l = (1 << 1), - OPT_n = (1 << 2) + OPT_n = (1 << 1) }; #if ENABLE_LONG_OPTS static const char longopts[] ALIGN1 = "seed-dir\0" Required_argument "d" - "lock-file\0" Required_argument "l" "skip-credit\0" No_argument "n" ; #endif - opt = getopt32long(argv, "d:l:n", longopts, &seed_dir, &lock_file); + opt = getopt32long(argv, "d:n", longopts, &seed_dir); if (!(opt & OPT_d) || !seed_dir) seed_dir = xstrdup(DEFAULT_SEED_DIR); - if (!(opt & OPT_l) || !lock_file) - lock_file = xstrdup(DEFAULT_LOCK_FILE); skip_credit = opt & OPT_n; creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); 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[]) if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) bb_simple_perror_msg_and_die("unable to create seed directory"); - lock = open(lock_file, O_WRONLY | O_CREAT, 0000); - if (lock < 0 || flock(lock, LOCK_EX) < 0) { - bb_simple_perror_msg("unable to open lock file"); - program_ret = 1; - goto out; - } - dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); - if (dfd < 0) { - bb_simple_perror_msg("unable to open seed directory"); + if (dfd < 0 || flock(dfd, LOCK_EX) < 0) { + bb_simple_perror_msg("unable to open and lock seed directory"); program_ret = 1; goto out; } @@ -271,26 +245,19 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) printf("Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable"); fd = open(non_creditable_seed, O_WRONLY | O_CREAT | O_TRUNC, 0400); - if (fd < 0) { - bb_simple_perror_msg("unable to open seed file for writing"); - program_ret |= 1 << 4; - goto out; - } - if (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_simple_perror_msg("unable to write seed file"); - program_ret |= 1 << 5; + program_ret |= 1 << 4; goto out; } if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) { bb_simple_perror_msg("unable to make new seed creditable"); - program_ret |= 1 << 6; + program_ret |= 1 << 5; } out: if (ENABLE_FEATURE_CLEAN_UP && fd >= 0) close(fd); if (ENABLE_FEATURE_CLEAN_UP && dfd >= 0) close(dfd); - if (ENABLE_FEATURE_CLEAN_UP && lock >= 0) - close(lock); return program_ret; } From rep.dot.nop at gmail.com Wed Apr 20 13:43:00 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:43:00 +0200 Subject: [git commit] seedrng: avoid needless runtime strlen() call Message-ID: <20220420133637.257B083DB0@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=3cb40f89de42aa694d44cb6e896b732fa062ee75 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master - Avoid needless runtime strlen() call, bloating binary. - Replace failed seed string with series of nulls. function old new delta .rodata 108350 108338 -12 static.seedrng_prefix 26 - -26 seedrng_main 1000 948 -52 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/2 up/down: 0/-90) Total: -90 bytes text data bss dec hex filename 975919 4227 1816 981962 efbca busybox_old 975829 4227 1816 981872 efb70 busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 49b9ab54b..5735dc059 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -21,7 +21,7 @@ */ //config:config SEEDRNG -//config: bool "seedrng (2.1 kb)" +//config: bool "seedrng (2 kb)" //config: default y //config: help //config: Seed the kernel RNG from seed files, meant to be called @@ -173,8 +173,6 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { - static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix"; - static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure"; char *seed_dir, *creditable_seed, *non_creditable_seed; int ret, fd = -1, dfd = -1, program_ret = 0; uint8_t new_seed[MAX_SEED_LEN]; @@ -218,7 +216,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) } sha256_begin(&hash); - sha256_hash(&hash, seedrng_prefix, strlen(seedrng_prefix)); + sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25); clock_gettime(CLOCK_REALTIME, ×tamp); sha256_hash(&hash, ×tamp, sizeof(timestamp)); clock_gettime(CLOCK_BOOTTIME, ×tamp); @@ -236,7 +234,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) if (ret < 0) { bb_simple_perror_msg("unable to read new seed"); new_seed_len = SHA256_OUTSIZE; - strncpy((char *)new_seed, seedrng_failure, new_seed_len); + memset(new_seed, 0, SHA256_OUTSIZE); program_ret |= 1 << 3; } sha256_hash(&hash, &new_seed_len, sizeof(new_seed_len)); From rep.dot.nop at gmail.com Wed Apr 20 13:42:53 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:42:53 +0200 Subject: [git commit] seedrng: hoist bb_strtoul out of min/max Message-ID: <20220420133636.F330883DB0@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=31ec481baf106cf9c6d8f34ae6a55ab1738dea6f branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master - Hoist bb_strtoul out of min/max to prevent quadruple evaluation. - Don't use separate variables for boottime/realtime. - Make use of ENABLE_FEATURE_CLEAN_UP where appropriate. - Order hash initialization after lock taking per Bernhard's taste. - Add comment description of theory of operation. function old new delta seed_from_file_if_exists 533 456 -77 seedrng_main 1218 1086 -132 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-209) Total: -209 bytes text data bss dec hex filename 976445 4227 1848 982520 efdf8 busybox_old 976236 4227 1848 982311 efd27 busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index d82a942aa..1bceae405 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -2,11 +2,26 @@ /* * Copyright (C) 2022 Jason A. Donenfeld . All Rights Reserved. * + * SeedRNG is a simple program made for seeding the Linux kernel random number + * generator from seed files. It is is useful in light of the fact that the + * Linux kernel RNG cannot be initialized from shell scripts, and new seeds + * cannot be safely generated from boot time shell scripts either. It should + * be run once at init time and once at shutdown time. It can be run at other + * times on a timer as well. Whenever it is run, it writes existing seed files + * into the RNG pool, and then creates a new seed file. If the RNG is + * initialized at the time of creating a new seed file, then that new seed file + * is marked as "creditable", which means it can be used to initialize the RNG. + * Otherwise, it is marked as "non-creditable", in which case it is still used + * to seed the RNG's pool, but will not initialize the RNG. In order to ensure + * that entropy only ever stays the same or increases from one seed file to the + * next, old seed values are hashed together with new seed values when writing + * new seed files. + * * This is based on code from . */ //config:config SEEDRNG -//config: bool "seedrng (2.6 kb)" +//config: bool "seedrng (2.5 kb)" //config: default y //config: help //config: Seed the kernel RNG from seed files, meant to be called @@ -71,12 +86,14 @@ enum seedrng_lengths { static size_t determine_optimal_seed_len(void) { char poolsize_str[11] = { 0 }; + unsigned long poolsize; if (open_read_close("/proc/sys/kernel/random/poolsize", poolsize_str, sizeof(poolsize_str) - 1) < 0) { bb_perror_msg("unable to determine pool size, falling back to %u bits", MIN_SEED_LEN * 8); return MIN_SEED_LEN; } - return MAX(MIN((bb_strtoul(poolsize_str, NULL, 10) + 7) / 8, MAX_SEED_LEN), MIN_SEED_LEN); + poolsize = (bb_strtoul(poolsize_str, NULL, 10) + 7) / 8; + return MAX(MIN(poolsize, MAX_SEED_LEN), MIN_SEED_LEN); } static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) @@ -130,7 +147,8 @@ static int seed_rng(uint8_t *seed, size_t len, bool credit) ret = ioctl(random_fd, RNDADDENTROPY, &req); if (ret) ret = -errno ? -errno : -EIO; - close(random_fd); + if (ENABLE_FEATURE_CLEAN_UP) + close(random_fd); errno = -ret; return ret ? -1 : 0; } @@ -171,7 +189,7 @@ static int seed_from_file_if_exists(const char *filename, bool credit, sha256_ct if (ret < 0) bb_simple_perror_msg("unable to seed"); out: - if (dfd >= 0) + if (ENABLE_FEATURE_CLEAN_UP && dfd >= 0) close(dfd); errno = -ret; return ret ? -1 : 0; @@ -187,7 +205,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) size_t new_seed_len; bool new_seed_creditable; bool skip_credit = false; - struct timespec realtime = { 0 }, boottime = { 0 }; + struct timespec timestamp = { 0 }; sha256_ctx_t hash; int opt; @@ -217,13 +235,6 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) if (getuid()) bb_simple_error_msg_and_die("this program requires root"); - sha256_begin(&hash); - sha256_hash(&hash, seedrng_prefix, strlen(seedrng_prefix)); - clock_gettime(CLOCK_REALTIME, &realtime); - clock_gettime(CLOCK_BOOTTIME, &boottime); - sha256_hash(&hash, &realtime, sizeof(realtime)); - sha256_hash(&hash, &boottime, sizeof(boottime)); - if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) bb_simple_perror_msg_and_die("unable to create seed directory"); @@ -234,6 +245,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) goto out; } + sha256_begin(&hash); + sha256_hash(&hash, seedrng_prefix, strlen(seedrng_prefix)); + clock_gettime(CLOCK_REALTIME, ×tamp); + sha256_hash(&hash, ×tamp, sizeof(timestamp)); + clock_gettime(CLOCK_BOOTTIME, ×tamp); + sha256_hash(&hash, ×tamp, sizeof(timestamp)); + ret = seed_from_file_if_exists(non_creditable_seed, false, &hash); if (ret < 0) program_ret |= 1 << 1; @@ -270,9 +288,9 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) program_ret |= 1 << 6; } out: - if (fd >= 0) + if (ENABLE_FEATURE_CLEAN_UP && fd >= 0) close(fd); - if (lock >= 0) + if (ENABLE_FEATURE_CLEAN_UP && lock >= 0) close(lock); return program_ret; } From rep.dot.nop at gmail.com Wed Apr 20 13:43:04 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:43:04 +0200 Subject: [git commit] seedrng: compress format strings with %s arguments Message-ID: <20220420133637.2F60883DAC@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=57fea029cc3d6faf5a8b9ad4b17b543359fe7ccb branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master - Avoid an xstrdup call with seed_dir. - Compress format strings with %s arguments. - Open /dev/urandom for add entropy ioctl rather than /dev/random, so that /dev/random is only used for the already-sightly-flawed poll() check for creditability. function old new delta seedrng_main 948 958 +10 seed_from_file_if_exists 410 417 +7 .rodata 108338 108206 -132 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 17/-132) Total: -115 bytes text data bss dec hex filename 975829 4227 1816 981872 efb70 busybox_old 975714 4227 1816 981757 efafd busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 5735dc059..5a41addf0 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -129,7 +129,7 @@ static int seed_rng(uint8_t *seed, size_t len, bool credit) } memcpy(req.buffer, seed, len); - random_fd = open("/dev/random", O_RDONLY); + random_fd = open("/dev/urandom", O_RDONLY); if (random_fd < 0) return -1; ret = ioctl(random_fd, RNDADDENTROPY, &req); @@ -150,11 +150,11 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, if (seed_len < 0) { if (errno == ENOENT) return 0; - bb_simple_perror_msg("unable to read seed file"); + bb_perror_msg("unable to%s seed", " read"); return -1; } if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { - bb_simple_perror_msg("unable to remove seed, so not seeding"); + bb_perror_msg("unable to%s seed", " remove"); return -1; } else if (!seed_len) return 0; @@ -164,7 +164,7 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, printf("Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without"); if (seed_rng(seed, seed_len, credit) < 0) { - bb_simple_perror_msg("unable to seed"); + bb_perror_msg("unable to%s seed", ""); return -1; } return 0; @@ -173,7 +173,7 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { - char *seed_dir, *creditable_seed, *non_creditable_seed; + const char *seed_dir = DEFAULT_SEED_DIR, *creditable_seed, *non_creditable_seed; int ret, fd = -1, dfd = -1, program_ret = 0; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; @@ -195,8 +195,6 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) #endif opt = getopt32long(argv, "d:n", longopts, &seed_dir); - if (!(opt & OPT_d) || !seed_dir) - seed_dir = xstrdup(DEFAULT_SEED_DIR); skip_credit = opt & OPT_n; creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME); @@ -206,11 +204,11 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) bb_simple_error_msg_and_die(bb_msg_you_must_be_root); if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) - bb_simple_perror_msg_and_die("unable to create seed directory"); + bb_perror_msg_and_die("unable to %s seed directory", "create"); dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); if (dfd < 0 || flock(dfd, LOCK_EX) < 0) { - bb_simple_perror_msg("unable to lock seed directory"); + bb_perror_msg("unable to %s seed directory", "lock"); program_ret = 1; goto out; } @@ -232,7 +230,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) new_seed_len = determine_optimal_seed_len(); ret = read_new_seed(new_seed, new_seed_len, &new_seed_creditable); if (ret < 0) { - bb_simple_perror_msg("unable to read new seed"); + bb_perror_msg("unable to%s seed", " read new"); new_seed_len = SHA256_OUTSIZE; memset(new_seed, 0, SHA256_OUTSIZE); program_ret |= 1 << 3; @@ -241,10 +239,10 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) sha256_hash(&hash, new_seed, new_seed_len); sha256_end(&hash, new_seed + new_seed_len - SHA256_OUTSIZE); - printf("Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable"); + printf("Saving %zu bits of %screditable seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "" : "non-"); fd = open(non_creditable_seed, 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_simple_perror_msg("unable to write seed file"); + bb_perror_msg("unable to%s seed", " write"); program_ret |= 1 << 4; goto out; } From rep.dot.nop at gmail.com Wed Apr 20 13:43:00 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:43:00 +0200 Subject: [git commit] seedrng: remove some global variables Message-ID: <20220420133637.08CA283DBB@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=3c60711f836b151b8f361098475c3b0cd162dd17 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master - Remove global variables and pass dfd by value, opened once instead of twice, which shaves off some more bytes. function old new delta seedrng_main 1086 1088 +2 seed_dir 8 - -8 non_creditable_seed 8 - -8 lock_file 8 - -8 creditable_seed 8 - -8 seed_from_file_if_exists 456 426 -30 ------------------------------------------------------------------------------ (add/remove: 0/4 grow/shrink: 1/1 up/down: 2/-62) Total: -60 bytes text data bss dec hex filename 976236 4227 1848 982311 efd27 busybox_old 976208 4227 1816 982251 efceb busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 1bceae405..53be5048a 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -21,7 +21,7 @@ */ //config:config SEEDRNG -//config: bool "seedrng (2.5 kb)" +//config: bool "seedrng (2.4 kb)" //config: default y //config: help //config: Seed the kernel RNG from seed files, meant to be called @@ -76,8 +76,6 @@ #define CREDITABLE_SEED_NAME "seed.credit" #define NON_CREDITABLE_SEED_NAME "seed.no-credit" -static char *seed_dir, *lock_file, *creditable_seed, *non_creditable_seed; - enum seedrng_lengths { MIN_SEED_LEN = SHA256_OUTSIZE, MAX_SEED_LEN = 512 @@ -153,18 +151,12 @@ static int seed_rng(uint8_t *seed, size_t len, bool credit) return ret ? -1 : 0; } -static int seed_from_file_if_exists(const char *filename, bool credit, sha256_ctx_t *hash) +static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, sha256_ctx_t *hash) { uint8_t seed[MAX_SEED_LEN]; ssize_t seed_len; - int dfd = -1, ret = 0; + int ret = 0; - dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); - if (dfd < 0) { - ret = -errno; - bb_simple_perror_msg("unable to open seed directory"); - goto out; - } seed_len = open_read_close(filename, seed, sizeof(seed)); if (seed_len < 0) { if (errno != ENOENT) { @@ -189,8 +181,6 @@ static int seed_from_file_if_exists(const char *filename, bool credit, sha256_ct if (ret < 0) bb_simple_perror_msg("unable to seed"); out: - if (ENABLE_FEATURE_CLEAN_UP && dfd >= 0) - close(dfd); errno = -ret; return ret ? -1 : 0; } @@ -200,7 +190,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix"; static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure"; - int ret, fd = -1, lock, program_ret = 0; + char *seed_dir, *lock_file, *creditable_seed, *non_creditable_seed; + int ret, fd = -1, dfd = -1, lock, program_ret = 0; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; bool new_seed_creditable; @@ -245,6 +236,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) goto out; } + dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); + if (dfd < 0) { + bb_simple_perror_msg("unable to open seed directory"); + program_ret = 1; + goto out; + } + sha256_begin(&hash); sha256_hash(&hash, seedrng_prefix, strlen(seedrng_prefix)); clock_gettime(CLOCK_REALTIME, ×tamp); @@ -252,10 +250,10 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) clock_gettime(CLOCK_BOOTTIME, ×tamp); sha256_hash(&hash, ×tamp, sizeof(timestamp)); - ret = seed_from_file_if_exists(non_creditable_seed, false, &hash); + ret = seed_from_file_if_exists(non_creditable_seed, dfd, false, &hash); if (ret < 0) program_ret |= 1 << 1; - ret = seed_from_file_if_exists(creditable_seed, !skip_credit, &hash); + ret = seed_from_file_if_exists(creditable_seed, dfd, !skip_credit, &hash); if (ret < 0) program_ret |= 1 << 2; @@ -290,6 +288,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) out: if (ENABLE_FEATURE_CLEAN_UP && fd >= 0) close(fd); + if (ENABLE_FEATURE_CLEAN_UP && dfd >= 0) + close(dfd); if (ENABLE_FEATURE_CLEAN_UP && lock >= 0) close(lock); return program_ret; From rep.dot.nop at gmail.com Wed Apr 20 13:20:29 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 15:20:29 +0200 Subject: [git commit] seedrng: import SeedRNG utility for kernel RNG seed files Message-ID: <20220420133636.DC34183DAC@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=4b407bacd4c1628782d24c3e044e43780bb057a4 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master The RNG can't actually be seeded from a shell script, due to the reliance on ioctls and the fact that entropy written into the unprivileged /dev/urandom device is not immediately mixed in, making subsequent seed reads dangerous. For this reason, the seedrng project provides a basic "C script" meant to be copy and pasted into projects like Busybox and tweaked as needed: . The SeedRNG construction has been part of systemd's seeder since January, and recently was added to Android, OpenRC, and Void's Runit, with more integrations on their way depending on context. Virtually every single Busybox-based distro I have seen seeds things in wrong, incomplete, or otherwise dangerous way. For example, fixing this issue in Buildroot requires first for Busybox to have this fix. This commit imports it into Busybox and wires up the basic config. The utility itself is tiny, and unlike the example code from the SeedRNG project, we can re-use libbb's existing hash functions, rather than having to ship a standalone BLAKE2s, which makes this even smaller. function old new delta seedrng_main - 1463 +1463 .rodata 107858 108665 +807 seed_from_file_if_exists - 697 +697 packed_usage 34414 34519 +105 static.longopts - 38 +38 static.seedrng_prefix - 26 +26 seed_dir - 8 +8 non_creditable_seed - 8 +8 lock_file - 8 +8 creditable_seed - 8 +8 applet_names 2747 2755 +8 applet_main 3192 3200 +8 ------------------------------------------------------------------------------ (add/remove: 9/0 grow/shrink: 4/0 up/down: 3184/0) Total: 3184 bytes text data bss dec hex filename 973776 4219 1816 979811 ef363 busybox_old 977035 4227 1848 983110 f0046 busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c new file mode 100644 index 000000000..2950acde0 --- /dev/null +++ b/util-linux/seedrng.c @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2022 Jason A. Donenfeld . All Rights Reserved. + * + * This is based on code from . + */ + +//config:config SEEDRNG +//config: bool "seedrng (3.8 kb)" +//config: default y +//config: help +//config: Seed the kernel RNG from seed files, meant to be called +//config: once during startup, once during shutdown, and optionally +//config: at some periodic interval in between. + +//applet:IF_SEEDRNG(APPLET(seedrng, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SEEDRNG) += seedrng.o + +//usage:#define seedrng_trivial_usage +//usage: "[-d SEED_DIRECTORY] [-l LOCK_FILE] [-n]" +//usage:#define seedrng_full_usage "\n\n" +//usage: "Seed the kernel RNG from seed files." +//usage: "\n" +//usage: "\n -d, --seed-dir DIR Use seed files from specified directory (default: /var/lib/seedrng)" +//usage: "\n -l, --lock-file FILE Use file as exclusive lock (default: /var/run/seedrng.lock)" +//usage: "\n -n, --skip-credit Skip crediting seeds, even if creditable" + +#include "libbb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef GRND_INSECURE +#define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ +#endif + +#ifndef LOCALSTATEDIR +#define LOCALSTATEDIR "/var/lib" +#endif +#ifndef RUNSTATEDIR +#define RUNSTATEDIR "/var/run" +#endif + +#define DEFAULT_SEED_DIR LOCALSTATEDIR "/seedrng" +#define DEFAULT_LOCK_FILE RUNSTATEDIR "/seedrng.lock" +#define CREDITABLE_SEED_NAME "seed.credit" +#define NON_CREDITABLE_SEED_NAME "seed.no-credit" + +static char *seed_dir, *lock_file, *creditable_seed, *non_creditable_seed; + +enum seedrng_lengths { + MAX_SEED_LEN = 512, + MIN_SEED_LEN = SHA256_OUTSIZE +}; + +#ifndef DIV_ROUND_UP +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +#endif + +static size_t determine_optimal_seed_len(void) +{ + size_t ret = 0; + char poolsize_str[11] = { 0 }; + int fd = open("/proc/sys/kernel/random/poolsize", O_RDONLY); + + if (fd < 0 || read(fd, poolsize_str, sizeof(poolsize_str) - 1) < 0) { + fprintf(stderr, "WARNING: Unable to determine pool size, falling back to %u bits: %s\n", MIN_SEED_LEN * 8, strerror(errno)); + ret = MIN_SEED_LEN; + } else + ret = DIV_ROUND_UP(strtoul(poolsize_str, NULL, 10), 8); + if (fd >= 0) + close(fd); + if (ret < MIN_SEED_LEN) + ret = MIN_SEED_LEN; + else if (ret > MAX_SEED_LEN) + ret = MAX_SEED_LEN; + return ret; +} + +static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) +{ + ssize_t ret; + int urandom_fd; + + *is_creditable = false; + ret = getrandom(seed, len, GRND_NONBLOCK); + if (ret == (ssize_t)len) { + *is_creditable = true; + return 0; + } else if (ret < 0 && errno == ENOSYS) { + struct pollfd random_fd = { + .fd = open("/dev/random", O_RDONLY), + .events = POLLIN + }; + if (random_fd.fd < 0) + return -errno; + *is_creditable = poll(&random_fd, 1, 0) == 1; + close(random_fd.fd); + } else if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len) + return 0; + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) + return -errno; + ret = read(urandom_fd, seed, len); + if (ret == (ssize_t)len) + ret = 0; + else + ret = -errno ? -errno : -EIO; + close(urandom_fd); + return ret; +} + +static int seed_rng(uint8_t *seed, size_t len, bool credit) +{ + struct { + int entropy_count; + int buf_size; + uint8_t buffer[MAX_SEED_LEN]; + } req = { + .entropy_count = credit ? len * 8 : 0, + .buf_size = len + }; + int random_fd, ret; + + if (len > sizeof(req.buffer)) + return -EFBIG; + memcpy(req.buffer, seed, len); + + random_fd = open("/dev/random", O_RDWR); + if (random_fd < 0) + return -errno; + ret = ioctl(random_fd, RNDADDENTROPY, &req); + if (ret) + ret = -errno ? -errno : -EIO; + close(random_fd); + return ret; +} + +static int seed_from_file_if_exists(const char *filename, bool credit, sha256_ctx_t *hash) +{ + uint8_t seed[MAX_SEED_LEN]; + ssize_t seed_len; + int fd, dfd, ret = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0 && errno == ENOENT) + return 0; + else if (fd < 0) { + ret = -errno; + fprintf(stderr, "ERROR: Unable to open seed file: %s\n", strerror(errno)); + return ret; + } + dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); + if (dfd < 0) { + ret = -errno; + close(fd); + fprintf(stderr, "ERROR: Unable to open seed directory: %s\n", strerror(errno)); + return ret; + } + seed_len = read(fd, seed, sizeof(seed)); + if (seed_len < 0) { + ret = -errno; + fprintf(stderr, "ERROR: Unable to read seed file: %s\n", strerror(errno)); + } + close(fd); + if (ret) { + close(dfd); + return ret; + } + if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { + ret = -errno; + fprintf(stderr, "ERROR: Unable to remove seed after reading, so not seeding: %s\n", strerror(errno)); + } + close(dfd); + if (ret) + return ret; + if (!seed_len) + return 0; + + sha256_hash(hash, &seed_len, sizeof(seed_len)); + sha256_hash(hash, seed, seed_len); + + fprintf(stdout, "Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without"); + ret = seed_rng(seed, seed_len, credit); + if (ret < 0) + fprintf(stderr, "ERROR: Unable to seed: %s\n", strerror(-ret)); + return ret; +} + +int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; +int seedrng_main(int argc UNUSED_PARAM, char *argv[]) +{ + static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix"; + static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure"; + int ret, fd = -1, lock, program_ret = 0; + uint8_t new_seed[MAX_SEED_LEN]; + size_t new_seed_len; + bool new_seed_creditable; + bool skip_credit = false; + struct timespec realtime = { 0 }, boottime = { 0 }; + sha256_ctx_t hash; + + int opt; + enum { + OPT_d = (1 << 0), + OPT_l = (1 << 1), + OPT_n = (1 << 2) + }; +#if ENABLE_LONG_OPTS + static const char longopts[] ALIGN1 = + "seed-dir\0" Required_argument "d" + "lock-file\0" Required_argument "l" + "skip-credit\0" No_argument "n" + ; +#endif + + opt = getopt32long(argv, "d:l:n", longopts, &seed_dir, &lock_file); + if (!(opt & OPT_d) || !seed_dir) + seed_dir = xstrdup(DEFAULT_SEED_DIR); + if (!(opt & OPT_l) || !lock_file) + lock_file = xstrdup(DEFAULT_LOCK_FILE); + skip_credit = opt & OPT_n; + creditable_seed = xasprintf("%s/%s", seed_dir, CREDITABLE_SEED_NAME); + non_creditable_seed = xasprintf("%s/%s", seed_dir, NON_CREDITABLE_SEED_NAME); + + umask(0077); + if (getuid()) { + fprintf(stderr, "ERROR: This program requires root\n"); + return 1; + } + + sha256_begin(&hash); + sha256_hash(&hash, seedrng_prefix, strlen(seedrng_prefix)); + clock_gettime(CLOCK_REALTIME, &realtime); + clock_gettime(CLOCK_BOOTTIME, &boottime); + sha256_hash(&hash, &realtime, sizeof(realtime)); + sha256_hash(&hash, &boottime, sizeof(boottime)); + + if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) { + fprintf(stderr, "ERROR: Unable to create \"%s\" directory: %s\n", seed_dir, strerror(errno)); + return 1; + } + + lock = open(lock_file, O_WRONLY | O_CREAT, 0000); + if (lock < 0 || flock(lock, LOCK_EX) < 0) { + fprintf(stderr, "ERROR: Unable to open lock file: %s\n", strerror(errno)); + program_ret = 1; + goto out; + } + + ret = seed_from_file_if_exists(non_creditable_seed, false, &hash); + if (ret < 0) + program_ret |= 1 << 1; + ret = seed_from_file_if_exists(creditable_seed, !skip_credit, &hash); + if (ret < 0) + program_ret |= 1 << 2; + + new_seed_len = determine_optimal_seed_len(); + ret = read_new_seed(new_seed, new_seed_len, &new_seed_creditable); + if (ret < 0) { + fprintf(stderr, "ERROR: Unable to read new seed: %s\n", strerror(-ret)); + new_seed_len = SHA256_OUTSIZE; + strncpy((char *)new_seed, seedrng_failure, new_seed_len); + program_ret |= 1 << 3; + } + 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); + + fprintf(stdout, "Saving %zu bits of %s seed for next boot\n", new_seed_len * 8, new_seed_creditable ? "creditable" : "non-creditable"); + fd = open(non_creditable_seed, O_WRONLY | O_CREAT | O_TRUNC, 0400); + if (fd < 0) { + fprintf(stderr, "ERROR: Unable to open seed file for writing: %s\n", strerror(errno)); + program_ret |= 1 << 4; + goto out; + } + if (write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) { + fprintf(stderr, "ERROR: Unable to write seed file: %s\n", strerror(errno)); + program_ret |= 1 << 5; + goto out; + } + if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) { + fprintf(stderr, "WARNING: Unable to make new seed creditable: %s\n", strerror(errno)); + program_ret |= 1 << 6; + } +out: + if (fd >= 0) + close(fd); + if (lock >= 0) + close(lock); + return program_ret; +} From rep.dot.nop at gmail.com Wed Apr 20 14:06:04 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Wed, 20 Apr 2022 16:06:04 +0200 Subject: [git commit] vi: fix backspace over tab in commands Message-ID: <20220420135933.8D6FF83DBB@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=c93eb1a95b1f06c145d4169a8776a318a2085e8b branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Colon and search commands are entered on the status line. Since the cursor position wasn't being tracked backspacing over a tab resulted in a mismatch between the actual and apparent content of the command. function old new delta get_input_line 178 180 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 2/0) Total: 2 bytes Signed-off-by: Ron Yorston Signed-off-by: Bernhard Reutner-Fischer --- editors/vi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/editors/vi.c b/editors/vi.c index 4257c0fdc..6fa0a4e18 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -1217,10 +1217,11 @@ static char *get_input_line(const char *prompt) break; // this is end of input if (isbackspace(c)) { // user wants to erase prev char - write1("\b \b"); // erase char on screen buf[--i] = '\0'; + go_bottom_and_clear_to_eol(); if (i <= 0) // user backs up before b-o-l, exit break; + write1(buf); } else if (c > 0 && c < 256) { // exclude Unicode // (TODO: need to handle Unicode) buf[i] = c; From bugzilla at busybox.net Wed Apr 20 14:48:02 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 20 Apr 2022 14:48:02 +0000 Subject: [Bug 14726] Blank password in /etc/passwd results in no username displayed in a prompt In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14726 --- Comment #1 from Oliver Endriss --- Note that all functions which get the user name from /etc/passwd are affected: ls -l, ps, whoami, etc. The bug was introduced by commit c9fc15359ef8fe5aa98ab0308c1563d9bcf99bb8 With this commit, nth_string() does not longer work with an empty field in the middle of the line, for example an empty password field in /etc/password. Please revert this commit! Regards, Oliver -- You are receiving this mail because: You are on the CC list for the bug. From rep.dot.nop at gmail.com Thu Apr 21 11:37:10 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Thu, 21 Apr 2022 13:37:10 +0200 Subject: [git commit] kbuild: fix building sha256 Message-ID: <20220421113019.3557783FAE@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=831c754c91f798c53a133bc2cb84eaf38ed32352 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Pass down the correct EXTRA_CFLAGS to the compiler driver when building assembler source. Otherwise building busybox for a multilib other than the default failed to link since hash_md5_sha256_x86-64_shaNI.o and hash_md5_sha_x86-64_shaNI.o were built for the default arch which might not what we requested in the EXTRA_CFLAGS. Signed-off-by: Bernhard Reutner-Fischer --- Makefile | 8 -------- scripts/Makefile.lib | 1 + 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Makefile b/Makefile index b2ce46c7c..503475fe9 100644 --- a/Makefile +++ b/Makefile @@ -1301,14 +1301,6 @@ quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs))) quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files))) cmd_rmfiles = rm -f $(rm-files) - -a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \ - $(NOSTDINC_FLAGS) $(CPPFLAGS) \ - $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) - -quiet_cmd_as_o_S = AS $@ -cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< - # read all saved command lines targets := $(wildcard $(sort $(targets))) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index d8d768a28..ac1ac9735 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -113,6 +113,7 @@ c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \ $(basename_flags) $(modname_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \ + $(__c_flags) \ $(__a_flags) $(modkern_aflags) cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags) From rep.dot.nop at gmail.com Sun Apr 24 08:03:59 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Sun, 24 Apr 2022 10:03:59 +0200 Subject: [git commit] seedrng: prune header includes Message-ID: <20220424075655.1169E83993@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=05c366a56095d116f0f8f331f3d494d9580baf33 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Remove redundant includes. We have platform specific handling in libbb.h and platform.h so we can handle quirks in a central place. Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 374e7f676..f7434fb79 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -44,21 +44,7 @@ #include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #ifndef GRND_INSECURE #define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ From rep.dot.nop at gmail.com Sun Apr 24 08:01:07 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Sun, 24 Apr 2022 10:01:07 +0200 Subject: [git commit] seedrng: code-golf even smaller Message-ID: <20220424075655.05D3B83FA0@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=f9ea8ba5ed6d43b8b233eac433521eb158e359d1 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Since we're passing 0 as the timeout, we don't need safe_poll. Remove cleanup at end of program, since OS does that, which lets us simplify control flow. Factor repeated function calls into ternary loop. function old new delta seedrng_main 1061 1459 +398 seed_from_file_if_exists 468 - -468 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/0 up/down: 398/-468) Total: -70 bytes text data bss dec hex filename 1052781 16515 1816 1071112 105808 busybox_old 1052711 16515 1816 1071042 1057c2 busybox_unstripped Signed-off-by: Jason A. Donenfeld Signed-off-by: Bernhard Reutner-Fischer --- util-linux/seedrng.c | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 5a41addf0..374e7f676 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -102,7 +102,7 @@ static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) }; if (random_fd.fd < 0) return -1; - *is_creditable = safe_poll(&random_fd, 1, 0) == 1; + *is_creditable = poll(&random_fd, 1, 0) == 1; close(random_fd.fd); } else if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len) return 0; @@ -174,15 +174,13 @@ int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { const char *seed_dir = DEFAULT_SEED_DIR, *creditable_seed, *non_creditable_seed; - int ret, fd = -1, dfd = -1, program_ret = 0; + int fd, dfd, program_ret = 0; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; - bool new_seed_creditable; - bool skip_credit = false; + bool new_seed_creditable, skip_credit = false; struct timespec timestamp = { 0 }; sha256_ctx_t hash; - int opt; enum { OPT_d = (1 << 0), OPT_n = (1 << 1) @@ -194,8 +192,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) ; #endif - opt = getopt32long(argv, "d:n", longopts, &seed_dir); - skip_credit = opt & OPT_n; + skip_credit = getopt32long(argv, "d:n", longopts, &seed_dir) & OPT_n; creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME); @@ -207,11 +204,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) bb_perror_msg_and_die("unable to %s seed directory", "create"); dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); - if (dfd < 0 || flock(dfd, LOCK_EX) < 0) { - bb_perror_msg("unable to %s seed directory", "lock"); - program_ret = 1; - goto out; - } + if (dfd < 0 || flock(dfd, LOCK_EX) < 0) + bb_perror_msg_and_die("unable to %s seed directory", "lock"); sha256_begin(&hash); sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25); @@ -220,16 +214,14 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) clock_gettime(CLOCK_BOOTTIME, ×tamp); sha256_hash(&hash, ×tamp, sizeof(timestamp)); - ret = seed_from_file_if_exists(non_creditable_seed, dfd, false, &hash); - if (ret < 0) - program_ret |= 1 << 1; - ret = seed_from_file_if_exists(creditable_seed, dfd, !skip_credit, &hash); - if (ret < 0) - program_ret |= 1 << 2; + for (int i = 1; i < 3; ++i) { + if (seed_from_file_if_exists(i == 1 ? non_creditable_seed : creditable_seed, + dfd, i == 1 ? false : !skip_credit, &hash) < 0) + program_ret |= 1 << i; + } new_seed_len = determine_optimal_seed_len(); - ret = read_new_seed(new_seed, new_seed_len, &new_seed_creditable); - if (ret < 0) { + if (read_new_seed(new_seed, new_seed_len, &new_seed_creditable) < 0) { bb_perror_msg("unable to%s seed", " read new"); new_seed_len = SHA256_OUTSIZE; memset(new_seed, 0, SHA256_OUTSIZE); @@ -243,17 +235,11 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) fd = open(non_creditable_seed, 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("unable to%s seed", " write"); - program_ret |= 1 << 4; - goto out; + return program_ret | (1 << 4); } if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) { bb_simple_perror_msg("unable to make new seed creditable"); - program_ret |= 1 << 5; + return program_ret | (1 << 5); } -out: - if (ENABLE_FEATURE_CLEAN_UP && fd >= 0) - close(fd); - if (ENABLE_FEATURE_CLEAN_UP && dfd >= 0) - close(dfd); return program_ret; } From bugzilla at busybox.net Sun Apr 24 15:09:48 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sun, 24 Apr 2022 15:09:48 +0000 Subject: [Bug 14771] New: Feature Request: Busybox GZip -l compatibility Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14771 Bug ID: 14771 Summary: Feature Request: Busybox GZip -l compatibility Product: Busybox Version: 1.35.x Hardware: All OS: Linux Status: NEW Severity: enhancement Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: Synper311 at aol.com CC: busybox-cvs at busybox.net Target Milestone: --- There are a number of tools and scripts which assume the presence of the GZip -l argument to list the compressed file's contents, namely XArchiver and other archivers which work with system-present archivers. I reproduced the behavior on Alpine Linux Edge (v3.15.x) with Busybox v1.35.0 and XArchiver 0.5.4.17. GNU GZip documentation: https://www.gnu.org/software/gzip/manual/gzip.html#Sample Bug filed downstream with XArchiver: https://github.com/ib/xarchiver/issues/144 -- You are receiving this mail because: You are on the CC list for the bug. From rep.dot.nop at gmail.com Sun Apr 24 17:18:57 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Sun, 24 Apr 2022 19:18:57 +0200 Subject: [git commit] kbuild: Prefer -Oz over -Os Message-ID: <20220424170900.A49B483516@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=7fbfb2050f24a457a909ea6bcec85c49a21db83a branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master -Oz Optimize aggressively for size rather than speed. with gcc-12 so far (i think only https://gcc.gnu.org/PR32803 and 103773 ) "shorter load imm on x86_64": (add/remove: 0/0 grow/shrink: 4/1670 up/down: 6/-13196) Total: -13190 bytes text data bss dec hex filename 975753 4227 1816 981796 efb24 busybox_old 962442 4227 1816 968485 ec725 busybox_unstripped with clang-15: (add/remove: 394/34 grow/shrink: 161/1856 up/down: 18644/-98946)Total: -80302 bytes text data bss dec hex filename 1120994 16066 1696 1138756 116044 busybox_old 1040689 16026 1696 1058411 10266b busybox_unstripped Signed-off-by: Bernhard Reutner-Fischer --- Makefile.flags | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.flags b/Makefile.flags index c34356230..84cb00a75 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -87,14 +87,14 @@ endif #CFLAGS += $(call cc-option,-Wconversion,) ifneq ($(CONFIG_DEBUG),y) -CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,)) +CFLAGS += $(call cc-option,-Oz,$(call cc-option,-Os,$(call cc-option,-O2,))) else CFLAGS += $(call cc-option,-g,) #CFLAGS += "-D_FORTIFY_SOURCE=2" ifeq ($(CONFIG_DEBUG_PESSIMIZE),y) CFLAGS += $(call cc-option,-O0,) else -CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,)) +CFLAGS += $(call cc-option,-Oz,$(call cc-option,-Os,$(call cc-option,-O2,))) endif endif ifeq ($(CONFIG_DEBUG_SANITIZE),y) From bugzilla at busybox.net Wed Apr 27 06:17:40 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 27 Apr 2022 06:17:40 +0000 Subject: [Bug 14776] New: A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the getvar_i function(different CVE-2021-42378) Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14776 Bug ID: 14776 Summary: A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the getvar_i function(different CVE-2021-42378) Product: Busybox Version: 1.35.x Hardware: All OS: Linux Status: NEW Severity: major Priority: P5 Component: Standard Compliance Assignee: unassigned at busybox.net Reporter: magicgoogol at gmail.com CC: busybox-cvs at busybox.net Target Milestone: --- Created attachment 9296 --> https://bugs.busybox.net/attachment.cgi?id=9296&action=edit poc Discoverer: Taolaw at Vlab of Vecentek command: ./busybox_unstripped awk -f crash1 1.txt ================================================================= ==732311==ERROR: AddressSanitizer: heap-use-after-free on address 0x6060000018e0 at pc 0x560da89371db bp 0x7ffdf8e698b0 sp 0x7ffdf8e698a0 READ of size 4 at 0x6060000018e0 thread T0 #0 0x560da89371da in getvar_i editors/awk.c:1011 0x6060000018e0 is located 0 bytes inside of 64-byte region [0x6060000018e0,0x606000001920) freed by thread T0 here: #0 0x7f5a00e9440f in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:122 #1 0x560da8941305 in nvfree editors/awk.c:1840 #2 0x560da8bdddff (/home/test/fuzz/busybox-ASAN/busybox_unstripped+0x1044dff) previously allocated by thread T0 here: #0 0x7f5a00e94808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144 #1 0x560da84344a5 in xmalloc libbb/xfuncs_printf.c:50 #2 0x560da8bdddff (/home/test/fuzz/busybox-ASAN/busybox_unstripped+0x1044dff) SUMMARY: AddressSanitizer: heap-use-after-free editors/awk.c:1011 in getvar_i Shadow bytes around the buggy address: 0x0c0c7fff82c0: 00 00 04 fa fa fa fa fa 00 00 00 00 00 00 02 fa 0x0c0c7fff82d0: fa fa fa fa 00 00 00 00 00 00 02 fa fa fa fa fa 0x0c0c7fff82e0: 00 00 00 00 00 00 02 fa fa fa fa fa 00 00 00 00 0x0c0c7fff82f0: 00 00 00 03 fa fa fa fa 00 00 00 00 00 00 00 04 0x0c0c7fff8300: fa fa fa fa 00 00 00 00 00 00 00 04 fa fa fa fa =>0x0c0c7fff8310: 00 00 00 00 00 00 00 00 fa fa fa fa[fd]fd fd fd 0x0c0c7fff8320: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd 0x0c0c7fff8330: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa 0x0c0c7fff8340: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd 0x0c0c7fff8350: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fff8360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==732311==ABORTING -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Wed Apr 27 06:31:51 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 27 Apr 2022 06:31:51 +0000 Subject: [Bug 14781] New: A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14781 Bug ID: 14781 Summary: A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function Product: Busybox Version: 1.35.x Hardware: All OS: Linux Status: NEW Severity: major Priority: P5 Component: Standard Compliance Assignee: unassigned at busybox.net Reporter: magicgoogol at gmail.com CC: busybox-cvs at busybox.net Target Milestone: --- Created attachment 9301 --> https://bugs.busybox.net/attachment.cgi?id=9301&action=edit poc Discoverer: Taolaw at Vlab of Vecentek command: ./busybox_unstripped awk -f crash2 1.txt ================================================================= ==716531==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000001d60 at pc 0x55df2f6b595d bp 0x7fffc8cf08a0 sp 0x7fffc8cf0890 READ of size 4 at 0x606000001d60 thread T0 #0 0x55df2f6b595c in copyvar editors/awk.c:1051 0x606000001d60 is located 0 bytes inside of 64-byte region [0x606000001d60,0x606000001da0) freed by thread T0 here: #0 0x7f7b1aeec40f in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:122 #1 0x55df2f6bf305 in nvfree editors/awk.c:1840 #2 0x55df2f95bdff (/home/test/fuzz/busybox-ASAN/busybox_unstripped+0x1044dff) previously allocated by thread T0 here: #0 0x7f7b1aeec808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144 #1 0x55df2f1b24a5 in xmalloc libbb/xfuncs_printf.c:50 #2 0x55df2f95bdff (/home/test/fuzz/busybox-ASAN/busybox_unstripped+0x1044dff) SUMMARY: AddressSanitizer: heap-use-after-free editors/awk.c:1051 in copyvar Shadow bytes around the buggy address: 0x0c0c7fff8350: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd 0x0c0c7fff8360: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa 0x0c0c7fff8370: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd 0x0c0c7fff8380: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd 0x0c0c7fff8390: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa =>0x0c0c7fff83a0: fd fd fd fd fd fd fd fd fa fa fa fa[fd]fd fd fd 0x0c0c7fff83b0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd 0x0c0c7fff83c0: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa 0x0c0c7fff83d0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd 0x0c0c7fff83e0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd 0x0c0c7fff83f0: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==716531==ABORTING -- You are receiving this mail because: You are on the CC list for the bug. From vda.linux at googlemail.com Wed Apr 27 13:33:55 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 27 Apr 2022 15:33:55 +0200 Subject: [git commit] libbb: fix fallout from nth_string() robustification, closes 14726 Message-ID: <20220427132446.11EF9844FE@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=0cdd6f579256d7dcbf48548ee470b8bb54a7de64 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta parse_common 187 228 +41 Signed-off-by: Denys Vlasenko --- libpwdgrp/pwd_grp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index b44ada432..10debbcdb 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c @@ -191,6 +191,9 @@ static char *parse_common(FILE *fp, struct passdb *db, char *buf; while ((buf = xmalloc_fgetline(fp)) != NULL) { + int n; + char *field; + /* Skip empty lines, comment lines */ if (buf[0] == '\0' || buf[0] == '#') goto free_and_next; @@ -204,7 +207,16 @@ static char *parse_common(FILE *fp, struct passdb *db, /* no key specified: sequential read, return a record */ break; } - if (strcmp(key, nth_string(buf, field_pos)) == 0) { + /* Can't use nth_string() here, it does not allow empty strings + * ("\0\0" terminates the list), and a valid passwd entry + * "user::UID:GID..." would be mishandled */ + n = field_pos; + field = buf; + while (n) { + n--; + field += strlen(field) + 1; + } + if (strcmp(key, field) == 0) { /* record found */ break; } From bugzilla at busybox.net Wed Apr 27 14:11:26 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 27 Apr 2022 14:11:26 +0000 Subject: [Bug 14726] Blank password in /etc/passwd results in no username displayed in a prompt In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14726 Denys Vlasenko changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #2 from Denys Vlasenko --- Fixed in git. -- You are receiving this mail because: You are on the CC list for the bug. From vda.linux at googlemail.com Wed Apr 27 15:33:15 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 27 Apr 2022 17:33:15 +0200 Subject: [git commit] seedrng: shorten strings Message-ID: <20220427152324.85AD38454F@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=c82a0cd2b06f768ec569c42bbde328b1cebc347e branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta .rodata 104894 104876 -18 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index dd082ea90..441bb7b93 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -67,7 +67,7 @@ static size_t determine_optimal_seed_len(void) n = open_read_close("/proc/sys/kernel/random/poolsize", poolsize_str, sizeof(poolsize_str) - 1); if (n < 0) { - bb_perror_msg("unable to determine pool size, assuming %u bits", MIN_SEED_LEN * 8); + bb_perror_msg("can't determine pool size, assuming %u bits", MIN_SEED_LEN * 8); return MIN_SEED_LEN; } poolsize_str[n] = '\0'; @@ -139,11 +139,11 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, if (seed_len < 0) { if (errno == ENOENT) return 0; - bb_perror_msg("unable to%s seed", " read"); + bb_perror_msg("can't%s seed", " read"); return -1; } if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { - bb_perror_msg("unable to%s seed", " remove"); + bb_perror_msg("can't%s seed", " remove"); return -1; } else if (!seed_len) return 0; @@ -151,9 +151,9 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, sha256_hash(hash, &seed_len, sizeof(seed_len)); sha256_hash(hash, seed, seed_len); - printf("Seeding %zd bits %s crediting\n", seed_len * 8, credit ? "and" : "without"); + printf("Seeding %u bits %s crediting\n", (unsigned)seed_len * 8, credit ? "and" : "without"); if (seed_rng(seed, seed_len, credit) < 0) { - bb_perror_msg("unable to%s seed", ""); + bb_perror_msg("can't%s seed", ""); return -1; } return 0; @@ -188,11 +188,11 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) bb_simple_error_msg_and_die(bb_msg_you_must_be_root); if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) - bb_perror_msg_and_die("unable to %s seed directory", "create"); + bb_perror_msg_and_die("can't %s seed directory", "create"); dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); if (dfd < 0 || flock(dfd, LOCK_EX) < 0) - bb_perror_msg_and_die("unable to %s seed directory", "lock"); + bb_perror_msg_and_die("can't %s seed directory", "lock"); sha256_begin(&hash); sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25); @@ -211,7 +211,7 @@ 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("unable to%s seed", " read new"); + bb_perror_msg("can't%s seed", " read new"); new_seed_len = SHA256_OUTSIZE; memset(new_seed, 0, SHA256_OUTSIZE); program_ret |= 1 << 3; @@ -220,14 +220,14 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) sha256_hash(&hash, new_seed, new_seed_len); sha256_end(&hash, new_seed + new_seed_len - SHA256_OUTSIZE); - printf("Saving %zu bits of %screditable seed for next boot\n", 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, 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("unable to%s seed", " write"); + bb_perror_msg("can't%s seed", " write"); return program_ret | (1 << 4); } if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) { - bb_simple_perror_msg("unable to make new seed creditable"); + bb_simple_perror_msg("can't make new seed creditable"); return program_ret | (1 << 5); } return program_ret; From vda.linux at googlemail.com Wed Apr 27 14:54:18 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 27 Apr 2022 16:54:18 +0200 Subject: [git commit] seedrng: shrink --help text Message-ID: <20220427152324.653108454F@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=137b205722ed9a2e20f145d2f3e4106e8970fdad branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta packed_usage 34280 34253 -27 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index f7434fb79..6c02b735f 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -35,10 +35,10 @@ //usage:#define seedrng_trivial_usage //usage: "[-d SEED_DIRECTORY] [-n]" //usage:#define seedrng_full_usage "\n\n" -//usage: "Seed the kernel RNG from seed files." +//usage: "Seed the kernel RNG from seed files" //usage: "\n" -//usage: "\n -d, --seed-dir DIR Use seed files from specified directory (default: /var/lib/seedrng)" -//usage: "\n -n, --skip-credit Skip crediting seeds, even if creditable" +//usage: "\n -d DIR Use seed files from DIR (default: /var/lib/seedrng)" +//usage: "\n -n Skip crediting seeds, even if creditable" #include "libbb.h" From vda.linux at googlemail.com Wed Apr 27 15:20:43 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 27 Apr 2022 17:20:43 +0200 Subject: [git commit] seedrng: remove unnecessary zero-filling of local variables Message-ID: <20220427152324.7B16984551@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=401356511c5de3b5a88fdd3ac4977e19b82babf5 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta seedrng_main 1292 1273 -19 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index c762e9ecd..dd082ea90 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -54,20 +54,23 @@ #define CREDITABLE_SEED_NAME "seed.credit" #define NON_CREDITABLE_SEED_NAME "seed.no-credit" -enum seedrng_lengths { +enum { MIN_SEED_LEN = SHA256_OUTSIZE, MAX_SEED_LEN = 512 }; static size_t determine_optimal_seed_len(void) { - char poolsize_str[11] = { 0 }; - unsigned long poolsize; + char poolsize_str[12]; + unsigned poolsize; + int n; - if (open_read_close("/proc/sys/kernel/random/poolsize", poolsize_str, sizeof(poolsize_str) - 1) < 0) { + n = open_read_close("/proc/sys/kernel/random/poolsize", poolsize_str, sizeof(poolsize_str) - 1); + if (n < 0) { bb_perror_msg("unable to determine pool size, assuming %u bits", MIN_SEED_LEN * 8); return MIN_SEED_LEN; } + poolsize_str[n] = '\0'; poolsize = (bb_strtoul(poolsize_str, NULL, 10) + 7) / 8; return MAX(MIN(poolsize, MAX_SEED_LEN), MIN_SEED_LEN); } @@ -159,7 +162,7 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { - const char *seed_dir = DEFAULT_SEED_DIR, *creditable_seed, *non_creditable_seed; + const char *seed_dir, *creditable_seed, *non_creditable_seed; int fd, dfd, program_ret = 0; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; @@ -178,10 +181,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) ; #endif + seed_dir = DEFAULT_SEED_DIR; skip_credit = getopt32long(argv, "d:n", longopts, &seed_dir) & OPT_n; - creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); - non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME); - umask(0077); if (getuid()) bb_simple_error_msg_and_die(bb_msg_you_must_be_root); @@ -200,6 +201,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) clock_gettime(CLOCK_BOOTTIME, ×tamp); sha256_hash(&hash, ×tamp, sizeof(timestamp)); + creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); + non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME); for (int i = 1; i < 3; ++i) { if (seed_from_file_if_exists(i == 1 ? non_creditable_seed : creditable_seed, dfd, i == 1 ? false : !skip_credit, &hash) < 0) From vda.linux at googlemail.com Wed Apr 27 15:09:38 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 27 Apr 2022 17:09:38 +0200 Subject: [git commit] seedrng: remove unnecessary zero-filling of local variables Message-ID: <20220427152324.6EDD484550@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=6da9947358276d989e002c3c5c8ff2e33676ae21 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta seedrng_main 1323 1292 -31 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 6c02b735f..c762e9ecd 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -103,16 +103,16 @@ static int seed_rng(uint8_t *seed, size_t len, bool credit) int entropy_count; int buf_size; uint8_t buffer[MAX_SEED_LEN]; - } req = { - .entropy_count = credit ? len * 8 : 0, - .buf_size = len - }; + } req; int random_fd, ret; if (len > sizeof(req.buffer)) { errno = EFBIG; return -1; } + + req.entropy_count = credit ? len * 8 : 0; + req.buf_size = len; memcpy(req.buffer, seed, len); random_fd = open("/dev/urandom", O_RDONLY); @@ -164,7 +164,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; bool new_seed_creditable, skip_credit = false; - struct timespec timestamp = { 0 }; + struct timespec timestamp; sha256_ctx_t hash; enum { From vda.linux at googlemail.com Wed Apr 27 15:53:12 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 27 Apr 2022 17:53:12 +0200 Subject: [git commit] seedrng: chdir to the SEED_DIRECTORY - avoid concat_path_file's Message-ID: <20220427154351.C19EE84553@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=8456c21c09189da8eadb78ef5cc7fdb9825fbc13 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta seedrng_main 1273 1225 -48 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 441bb7b93..c42274759 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -162,7 +162,7 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { - const char *seed_dir, *creditable_seed, *non_creditable_seed; + const char *seed_dir; int fd, dfd, program_ret = 0; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; @@ -184,15 +184,15 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) seed_dir = DEFAULT_SEED_DIR; skip_credit = getopt32long(argv, "d:n", longopts, &seed_dir) & OPT_n; umask(0077); - if (getuid()) + if (getuid() != 0) bb_simple_error_msg_and_die(bb_msg_you_must_be_root); if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) bb_perror_msg_and_die("can't %s seed directory", "create"); - dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); if (dfd < 0 || flock(dfd, LOCK_EX) < 0) bb_perror_msg_and_die("can't %s seed directory", "lock"); + xfchdir(dfd); sha256_begin(&hash); sha256_hash(&hash, "SeedRNG v1 Old+New Prefix", 25); @@ -201,11 +201,11 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) clock_gettime(CLOCK_BOOTTIME, ×tamp); sha256_hash(&hash, ×tamp, sizeof(timestamp)); - creditable_seed = concat_path_file(seed_dir, CREDITABLE_SEED_NAME); - non_creditable_seed = concat_path_file(seed_dir, NON_CREDITABLE_SEED_NAME); for (int i = 1; i < 3; ++i) { - if (seed_from_file_if_exists(i == 1 ? non_creditable_seed : creditable_seed, - dfd, i == 1 ? false : !skip_credit, &hash) < 0) + if (seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, + dfd, + i == 1 ? false : !skip_credit, + &hash) < 0) program_ret |= 1 << i; } @@ -221,12 +221,12 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) 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-"); - fd = open(non_creditable_seed, 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) { bb_perror_msg("can't%s seed", " write"); return program_ret | (1 << 4); } - if (new_seed_creditable && rename(non_creditable_seed, creditable_seed) < 0) { + if (new_seed_creditable && rename(NON_CREDITABLE_SEED_NAME, CREDITABLE_SEED_NAME) < 0) { bb_simple_perror_msg("can't make new seed creditable"); return program_ret | (1 << 5); } From bugzilla at busybox.net Fri Apr 29 20:47:18 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 29 Apr 2022 20:47:18 +0000 Subject: [Bug 13776] udhcpc allows short lease to expire In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=13776 --- Comment #15 from Paul --- Modem got another automatic firmware update from the ISP and busybox udhcpc is running perfectly again so as expected the modem firmware was to blame. -- You are receiving this mail because: You are on the CC list for the bug. From vda.linux at googlemail.com Sat Apr 30 12:33:14 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 14:33:14 +0200 Subject: [git commit] ifplugd: split -a into -a and -A, latter disables upping in iface creation Message-ID: <20220430122830.5E8CE84136@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=002d6ee46d7a188aff9530cf21363b4cf7795dc4 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master -a meant both "don't up iface before each link detection" and "don't up iface when it newly appears". But they are not the same. I have a dock station where eth1 appears when I attach the notebook to it (looks like it's hanging off a USB bus). IOW: appearance of this interface is functionally equivalent to attaching ethernet cable. ifplugd meant to be able to *automatically* handle this case. Currently, with -a, it couldn't: newly appearing iface stayed down, user had to manually up it. function old new delta packed_usage 34253 34296 +43 .rodata 104876 104877 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 44/0) Total: 44 bytes Signed-off-by: Denys Vlasenko --- networking/ifplugd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/networking/ifplugd.c b/networking/ifplugd.c index c4b6b9584..0b55bf4e5 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -28,6 +28,7 @@ //usage: "\n -a Don't up interface at each link probe" //usage: "\n -M Monitor creation/destruction of interface" //usage: "\n (otherwise it must exist)" +//usage: "\n -A Don't up newly appeared interface" //usage: "\n -r PROG Script to run" //usage: "\n -x ARG Extra argument for script" //usage: "\n -I Don't exit on nonzero exit code from script" @@ -94,7 +95,7 @@ Netlink code then can be just dropped (1k or more?) #define IFPLUGD_ENV_CURRENT "IFPLUGD_CURRENT" enum { - FLAG_NO_AUTO = 1 << 0, // -a, Do not enable interface automatically + FLAG_NO_AUTO = 1 << 0, // -a, Don't up interface at each link probe FLAG_NO_DAEMON = 1 << 1, // -n, Do not daemonize FLAG_NO_SYSLOG = 1 << 2, // -s, Do not use syslog, use stderr instead FLAG_IGNORE_FAIL = 1 << 3, // -f, Ignore detection failure, retry instead (failure is treated as DOWN) @@ -111,14 +112,15 @@ enum { FLAG_INITIAL_DOWN = 1 << 14, // -l, Run "down" script on startup if no cable is detected FLAG_EXTRA_ARG = 1 << 15, // -x, Specify an extra argument for action script FLAG_MONITOR = 1 << 16, // -M, Use interface monitoring + FLAG_NO_UP_NEW_IFACE = 1 << 17, // -A, Don't up newly appeared interface #if ENABLE_FEATURE_PIDFILE - FLAG_KILL = 1 << 17, // -k, Kill a running daemon + FLAG_KILL = 1 << 18, // -k, Kill a running daemon #endif }; #if ENABLE_FEATURE_PIDFILE -# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:Mk" +# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:MAk" #else -# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:M" +# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:MA" #endif enum { // interface status @@ -387,7 +389,7 @@ static void up_iface(void) static void maybe_up_new_iface(void) { - if (!(option_mask32 & FLAG_NO_AUTO)) + if (!(option_mask32 & FLAG_NO_UP_NEW_IFACE)) up_iface(); #if 0 /* bloat */ From vda.linux at googlemail.com Sat Apr 30 13:17:32 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 15:17:32 +0200 Subject: [git commit] seedrng: do not try to continue on unexpected errors (just exit) Message-ID: <20220430130746.3391884219@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=0fa16fc7a2e03d4fadae3cd52f59656277f29f9d branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta .rodata 104946 104938 -8 seedrng_main 1225 1077 -148 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-156) Total: -156 bytes Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 54 ++++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index c42274759..82c69b72b 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -100,63 +100,43 @@ static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) return -1; } -static int seed_rng(uint8_t *seed, size_t len, bool credit) +static void seed_rng(uint8_t *seed, size_t len, bool credit) { struct { int entropy_count; int buf_size; uint8_t buffer[MAX_SEED_LEN]; } req; - int random_fd, ret; - - if (len > sizeof(req.buffer)) { - errno = EFBIG; - return -1; - } + int random_fd; req.entropy_count = credit ? len * 8 : 0; req.buf_size = len; memcpy(req.buffer, seed, len); - random_fd = open("/dev/urandom", O_RDONLY); - if (random_fd < 0) - return -1; - ret = ioctl(random_fd, RNDADDENTROPY, &req); - if (ret) - ret = -errno ? -errno : -EIO; + random_fd = xopen("/dev/urandom", O_RDONLY); + xioctl(random_fd, RNDADDENTROPY, &req); if (ENABLE_FEATURE_CLEAN_UP) close(random_fd); - errno = -ret; - return ret ? -1 : 0; } -static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, sha256_ctx_t *hash) +static void seed_from_file_if_exists(const char *filename, bool credit, sha256_ctx_t *hash) { uint8_t seed[MAX_SEED_LEN]; ssize_t seed_len; seed_len = open_read_close(filename, seed, sizeof(seed)); if (seed_len < 0) { - if (errno == ENOENT) - return 0; - bb_perror_msg("can't%s seed", " read"); - return -1; + if (errno != ENOENT) + bb_perror_msg_and_die("can't%s seed", " read"); + return; } - if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { - bb_perror_msg("can't%s seed", " remove"); - return -1; - } else if (!seed_len) - return 0; - - sha256_hash(hash, &seed_len, sizeof(seed_len)); - sha256_hash(hash, seed, seed_len); - - printf("Seeding %u bits %s crediting\n", (unsigned)seed_len * 8, credit ? "and" : "without"); - if (seed_rng(seed, seed_len, credit) < 0) { - bb_perror_msg("can't%s seed", ""); - return -1; + xunlink(filename); + if (seed_len != 0) { + sha256_hash(hash, &seed_len, sizeof(seed_len)); + sha256_hash(hash, seed, seed_len); + printf("Seeding %u bits %s crediting\n", (unsigned)seed_len * 8, credit ? "and" : "without"); + seed_rng(seed, seed_len, credit); } - return 0; } int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; @@ -202,11 +182,9 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) sha256_hash(&hash, ×tamp, sizeof(timestamp)); for (int i = 1; i < 3; ++i) { - if (seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, - dfd, + seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, i == 1 ? false : !skip_credit, - &hash) < 0) - program_ret |= 1 << i; + &hash); } new_seed_len = determine_optimal_seed_len(); From vda.linux at googlemail.com Sat Apr 30 13:25:55 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 15:25:55 +0200 Subject: [git commit] seedrng: prepare read_new_seed() to not need a "success" retval Message-ID: <20220430133023.786B8842E4@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=282b61a64921775e5d167df942347a8a3cf984e7 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master We do not expect /dev/[u]random to be not openable/readable. If they are, just bail out (something is obviously very wrong). function old new delta seedrng_main 1077 1076 -1 .rodata 104939 104929 -10 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 82c69b72b..3f4c5c0c8 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -79,25 +79,27 @@ static int read_new_seed(uint8_t *seed, size_t len, bool *is_creditable) { ssize_t ret; - *is_creditable = false; ret = getrandom(seed, len, GRND_NONBLOCK); if (ret == (ssize_t)len) { *is_creditable = true; return 0; - } else if (ret < 0 && errno == ENOSYS) { + } + if (ret < 0 && errno == ENOSYS) { struct pollfd random_fd = { - .fd = open("/dev/random", O_RDONLY), + .fd = xopen("/dev/random", O_RDONLY), .events = POLLIN }; - if (random_fd.fd < 0) - return -1; *is_creditable = poll(&random_fd, 1, 0) == 1; close(random_fd.fd); - } else if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len) - return 0; - if (open_read_close("/dev/urandom", seed, len) == (ssize_t)len) - return 0; - return -1; + } else { + *is_creditable = false; + if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len) + return 0; + } + 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; } static void seed_rng(uint8_t *seed, size_t len, bool credit) From vda.linux at googlemail.com Sat Apr 30 13:38:44 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 15:38:44 +0200 Subject: [git commit] seedrng: code shrink Message-ID: <20220430133023.88C0784338@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=2cbfd01c150420199a9cb74f5de72d7279e6cd11 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Struct initializers do this double init: ># util-linux/seedrng.c:88: struct pollfd random_fd = { movl $0, 132(%esp) #, random_fd movl $0, 136(%esp) #, random_fd ... ># util-linux/seedrng.c:88: struct pollfd random_fd = { movl %eax, 140(%esp) # _110, random_fd.fd movw $1, 144(%esp) #, random_fd.events and close(random_fd.fd) needs to pull the item from the stack: pushl 132(%esp) # random_fd.fd call close # function old new delta seedrng_main 1076 1050 -26 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 5559ba77c..023ed8688 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -85,14 +85,14 @@ static bool read_new_seed(uint8_t *seed, size_t len) return true; } if (ret < 0 && errno == ENOSYS) { - struct pollfd random_fd = { - .fd = xopen("/dev/random", O_RDONLY), - .events = POLLIN - }; + int fd = xopen("/dev/random", O_RDONLY); + struct pollfd random_fd; + random_fd.fd = fd; + random_fd.events = POLLIN; 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(fd); } else { if (getrandom(seed, len, GRND_INSECURE) == (ssize_t)len) return false; From vda.linux at googlemail.com Sat Apr 30 13:33:28 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 15:33:28 +0200 Subject: [git commit] seedrng: simplify read_new_seed() to not have error return Message-ID: <20220430133023.804CC842F3@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=52f3cf7e5f8c2635ffd456602b74118cf86ec099 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master gcc in fact detects this and does this transformation when generating code - no object code changes. Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 3f4c5c0c8..5559ba77c 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"); From vda.linux at googlemail.com Sat Apr 30 13:45:53 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 15:45:53 +0200 Subject: [git commit] seedrng: use more xfuncs where appropriate Message-ID: <20220430134042.860DE84552@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=d49da38aa38a3d9a28447fc725b3d43a3fabc7b4 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta .rodata 104929 104898 -31 seedrng_main 1050 1011 -39 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 023ed8688..978860bbd 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -143,7 +143,8 @@ static void seed_from_file_if_exists(const char *filename, bool credit, sha256_c if (seed_len != 0) { sha256_hash(hash, &seed_len, sizeof(seed_len)); sha256_hash(hash, seed, seed_len); - printf("Seeding %u bits %s crediting\n", (unsigned)seed_len * 8, credit ? "and" : "without"); + printf("Seeding %u bits %s crediting\n", + (unsigned)seed_len * 8, credit ? "and" : "without"); seed_rng(seed, seed_len, credit); } } @@ -152,7 +153,7 @@ int seedrng_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { const char *seed_dir; - int fd, dfd, program_ret = 0; + int fd, dfd; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; bool new_seed_creditable, skip_credit = false; @@ -178,8 +179,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) bb_perror_msg_and_die("can't %s seed directory", "create"); - dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); - if (dfd < 0 || flock(dfd, LOCK_EX) < 0) + dfd = xopen(seed_dir, O_DIRECTORY | O_RDONLY); + if (flock(dfd, LOCK_EX) < 0) bb_perror_msg_and_die("can't %s seed directory", "lock"); xfchdir(dfd); @@ -204,14 +205,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) 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) { + fd = xopen3(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400); + xwrite(fd, new_seed, new_seed_len); + if (fsync(fd) < 0) { bb_perror_msg("can't%s seed", " write"); - return program_ret | (1 << 4); + return (1 << 4); } - if (new_seed_creditable && rename(NON_CREDITABLE_SEED_NAME, CREDITABLE_SEED_NAME) < 0) { - bb_simple_perror_msg("can't make new seed creditable"); - return program_ret | (1 << 5); - } - return program_ret; + if (new_seed_creditable) + xrename(NON_CREDITABLE_SEED_NAME, CREDITABLE_SEED_NAME); + return EXIT_SUCCESS; } From vda.linux at googlemail.com Sat Apr 30 13:50:45 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 15:50:45 +0200 Subject: [git commit] seedrng: include fiel/dir names in error messages Message-ID: <20220430134042.9392A8428B@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=267178c62851a2e0fa3825bb49a67e362f41d4c0 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta .rodata 104898 104900 +2 seedrng_main 1011 1003 -8 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 2/-8) Total: -6 bytes Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 978860bbd..74bf633a7 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -136,7 +136,7 @@ static void seed_from_file_if_exists(const char *filename, bool credit, sha256_c seed_len = open_read_close(filename, seed, sizeof(seed)); if (seed_len < 0) { if (errno != ENOENT) - bb_perror_msg_and_die("can't%s seed", " read"); + bb_perror_msg_and_die("can't read '%s'", filename); return; } xunlink(filename); @@ -178,10 +178,10 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) bb_simple_error_msg_and_die(bb_msg_you_must_be_root); if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) - bb_perror_msg_and_die("can't %s seed directory", "create"); + bb_perror_msg_and_die("can't create directory '%s'", seed_dir); dfd = xopen(seed_dir, O_DIRECTORY | O_RDONLY); if (flock(dfd, LOCK_EX) < 0) - bb_perror_msg_and_die("can't %s seed directory", "lock"); + bb_perror_msg_and_die("can't lock seed directory"); xfchdir(dfd); sha256_begin(&hash); From vda.linux at googlemail.com Sat Apr 30 21:17:58 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 23:17:58 +0200 Subject: [git commit] seedrng: re-add fsync after unlink, and explain its purpose Message-ID: <20220430210822.BEE6484B96@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=464875411926d4085e3496f94551e532676d2e9d branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta seedrng_main 1003 1022 +19 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index 74bf633a7..b79ce6627 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -128,7 +128,7 @@ static void seed_rng(uint8_t *seed, size_t len, bool credit) close(random_fd); } -static void seed_from_file_if_exists(const char *filename, bool credit, sha256_ctx_t *hash) +static void seed_from_file_if_exists(const char *filename, int dfd, bool credit, sha256_ctx_t *hash) { uint8_t seed[MAX_SEED_LEN]; ssize_t seed_len; @@ -141,6 +141,16 @@ static void seed_from_file_if_exists(const char *filename, bool credit, sha256_c } xunlink(filename); if (seed_len != 0) { + /* We are going to use this data to seed the RNG: + * we believe it to genuinely containing entropy. + * If this just-unlinked file survives + * (e.g. if machine crashes _right now_) + * and we reuse it after reboot, this assumption + * would be violated. Fsync the directory to + * make sure file is gone: + */ + fsync(dfd); + sha256_hash(hash, &seed_len, sizeof(seed_len)); sha256_hash(hash, seed, seed_len); printf("Seeding %u bits %s crediting\n", @@ -193,6 +203,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) for (int i = 1; i < 3; ++i) { seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, + dfd, i == 1 ? false : !skip_credit, &hash); } From vda.linux at googlemail.com Sat Apr 30 21:53:28 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 30 Apr 2022 23:53:28 +0200 Subject: [git commit] seedrng: remove redundant assignment Message-ID: <20220430214322.61E0984BBA@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=0bca489b246d43df1c406b325b49d740141fdf75 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index b79ce6627..a02609a92 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -166,7 +166,7 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) int fd, dfd; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; - bool new_seed_creditable, skip_credit = false; + bool new_seed_creditable, skip_credit; struct timespec timestamp; sha256_ctx_t hash; @@ -176,8 +176,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) }; #if ENABLE_LONG_OPTS static const char longopts[] ALIGN1 = - "seed-dir\0" Required_argument "d" - "skip-credit\0" No_argument "n" + "seed-dir\0" Required_argument "d" + "skip-credit\0" No_argument "n" ; #endif From vda.linux at googlemail.com Sat Apr 30 23:50:44 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 1 May 2022 01:50:44 +0200 Subject: [git commit] seedrng: explain why we need locking and fsync'ing Message-ID: <20220430234129.AFBD084BC5@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=d5bd2e57a7be6c34393c52aa5e7ac2a8937da8d3 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master 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 --- util-linux/seedrng.c | 26 ++++++++++++++++++-------- 1 file 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[]) if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) bb_perror_msg_and_die("can't create directory '%s'", seed_dir); 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); + /* 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_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) { seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, dfd, - i == 1 ? false : !skip_credit, + /* credit? */ i == 1 ? false : !skip_credit, &hash); } @@ -218,11 +226,13 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) (unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-"); fd = xopen3(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400); xwrite(fd, new_seed, new_seed_len); - if (fsync(fd) < 0) { - bb_perror_msg("can't%s seed", " write"); - return (1 << 4); - } - if (new_seed_creditable) + if (new_seed_creditable) { + /* More paranoia when we create a file which we believe contains + * genuine entropy: make sure disk is not full, quota was't esceeded, etc: + */ + 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); + } return EXIT_SUCCESS; } From vda.linux at googlemail.com Sat Apr 30 23:58:57 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 1 May 2022 01:58:57 +0200 Subject: [git commit] seedrng: code shrink Message-ID: <20220501001126.48B7784BD9@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=fb4546c7af3d1d2f11fb7851b56104f5580f328f branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta seedrng_main 994 982 -12 Signed-off-by: Denys Vlasenko --- util-linux/seedrng.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c index c07bf84f7..3074e9a58 100644 --- a/util-linux/seedrng.c +++ b/util-linux/seedrng.c @@ -164,25 +164,27 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) { const char *seed_dir; int fd, dfd; + int i; + unsigned opts; uint8_t new_seed[MAX_SEED_LEN]; size_t new_seed_len; - bool new_seed_creditable, skip_credit; + bool new_seed_creditable; struct timespec timestamp; sha256_ctx_t hash; enum { - OPT_d = (1 << 0), - OPT_n = (1 << 1) + OPT_n = (1 << 0), /* must be 1 */ + OPT_d = (1 << 1), }; #if ENABLE_LONG_OPTS static const char longopts[] ALIGN1 = - "seed-dir\0" Required_argument "d" "skip-credit\0" No_argument "n" + "seed-dir\0" Required_argument "d" ; #endif seed_dir = DEFAULT_SEED_DIR; - skip_credit = getopt32long(argv, "d:n", longopts, &seed_dir) & OPT_n; + opts = getopt32long(argv, "nd:", longopts, &seed_dir); umask(0077); if (getuid() != 0) bb_simple_error_msg_and_die(bb_msg_you_must_be_root); @@ -209,10 +211,10 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) clock_gettime(CLOCK_BOOTTIME, ×tamp); sha256_hash(&hash, ×tamp, sizeof(timestamp)); - for (int i = 1; i < 3; ++i) { - seed_from_file_if_exists(i == 1 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, + for (i = 0; i <= 1; i++) { + seed_from_file_if_exists(i == 0 ? NON_CREDITABLE_SEED_NAME : CREDITABLE_SEED_NAME, dfd, - /* credit? */ i == 1 ? false : !skip_credit, + /* credit? */ (opts ^ OPT_n) & i, /* 0, then 1 unless -n */ &hash); }