From vda.linux at googlemail.com Mon Oct 2 11:56:32 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 Oct 2023 13:56:32 +0200 Subject: [git commit] sleep: fix "sleep -- ARGS" Message-ID: <20231002115701.BBE2C840C5@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=791b222dd55d3aa0e8b09be1be571e4829465dd6 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta sleep_main 116 119 +3 printf_main 860 837 -23 single_argv 50 25 -25 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 3/-48) Total: -45 bytes Signed-off-by: Denys Vlasenko --- coreutils/printf.c | 10 +++++----- coreutils/sleep.c | 4 ++-- include/libbb.h | 1 + libbb/single_argv.c | 15 +++++++++++---- shell/hush.c | 8 -------- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/coreutils/printf.c b/coreutils/printf.c index 7763d7c46..4edcfa9b5 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -425,9 +425,9 @@ int printf_main(int argc UNUSED_PARAM, char **argv) /* bash builtin errors out on "printf '-%s-\n' foo", * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo". * We will mimic coreutils. */ - if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && !argv[1][2]) - argv++; - if (!argv[1]) { + argv = skip_dash_dash(argv); + + if (!argv[0]) { if ((ENABLE_ASH_PRINTF || ENABLE_HUSH_PRINTF) && applet_name[0] != 'p' ) { @@ -437,8 +437,8 @@ int printf_main(int argc UNUSED_PARAM, char **argv) bb_show_usage(); } - format = argv[1]; - argv2 = argv + 2; + format = argv[0]; + argv2 = argv + 1; conv_err = 0; do { diff --git a/coreutils/sleep.c b/coreutils/sleep.c index 6edff59cc..fa74f1fd4 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c @@ -71,8 +71,8 @@ int sleep_main(int argc UNUSED_PARAM, char **argv) * + we can't use bb_show_usage * + applet_name can be the name of the shell */ - ++argv; - if (!*argv) { + argv = skip_dash_dash(argv); + if (!argv[0]) { /* Without this, bare "sleep" in ash shows _ash_ --help */ /* (ash can be the "sh" applet as well, so check 2nd char) */ if (ENABLE_ASH_SLEEP && applet_name[1] != 'l') { diff --git a/include/libbb.h b/include/libbb.h index eb97a9880..0883fb565 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1344,6 +1344,7 @@ int sanitize_env_if_suid(void) FAST_FUNC; /* For top, ps. Some argv[i] are replaced by malloced "-opt" strings */ void make_all_argv_opts(char **argv) FAST_FUNC; char* single_argv(char **argv) FAST_FUNC; +char **skip_dash_dash(char **argv) FAST_FUNC; extern const char *const bb_argv_dash[]; /* { "-", NULL } */ extern uint32_t option_mask32; uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; diff --git a/libbb/single_argv.c b/libbb/single_argv.c index 64844ddf8..594cb0d8d 100644 --- a/libbb/single_argv.c +++ b/libbb/single_argv.c @@ -8,11 +8,18 @@ */ #include "libbb.h" -char* FAST_FUNC single_argv(char **argv) +char** FAST_FUNC skip_dash_dash(char **argv) { - if (argv[1] && strcmp(argv[1], "--") == 0) + argv++; + if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0') argv++; - if (!argv[1] || argv[2]) + return argv; +} + +char* FAST_FUNC single_argv(char **argv) +{ + argv = skip_dash_dash(argv); + if (!argv[0] || argv[1]) bb_show_usage(); - return argv[1]; + return argv[0]; } diff --git a/shell/hush.c b/shell/hush.c index 8e632e0af..ca01e2b5b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -10883,14 +10883,6 @@ static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM) } #endif -static char **skip_dash_dash(char **argv) -{ - argv++; - if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0') - argv++; - return argv; -} - static int FAST_FUNC builtin_cd(char **argv) { const char *newdir; From vda.linux at googlemail.com Mon Oct 2 12:26:27 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 Oct 2023 14:26:27 +0200 Subject: [git commit] install: Fix chown resetting suid/sgid bits from chmod Message-ID: <20231002122703.288EC840E5@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=6d22c9abc29d43e919e819ff004fcd84a90de60b branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Since Linux 2.2.13, chown(2) resets the suid/gid bits for all users. This patch changes the ordering so that chmod gets called after chown. This behavior follows GNU coreutils. Signed-off-by: Nero Signed-off-by: Denys Vlasenko --- coreutils/install.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/coreutils/install.c b/coreutils/install.c index c0f1c538a..00f8be87e 100644 --- a/coreutils/install.c +++ b/coreutils/install.c @@ -244,6 +244,15 @@ int install_main(int argc, char **argv) } } + /* Set the user and group id */ + /* (must be before chmod, or else chown may clear suid/gid bits) */ + if ((opts & (OPT_OWNER|OPT_GROUP)) + && lchown(dest, uid, gid) == -1 + ) { + bb_perror_msg("can't change %s of %s", "ownership", dest); + ret = EXIT_FAILURE; + } + /* Set the file mode (always, not only with -m). * GNU coreutils 6.10 is not affected by umask. */ if (chmod(dest, mode) == -1) { @@ -254,13 +263,6 @@ int install_main(int argc, char **argv) if (use_default_selinux_context) setdefaultfilecon(dest); #endif - /* Set the user and group id */ - if ((opts & (OPT_OWNER|OPT_GROUP)) - && lchown(dest, uid, gid) == -1 - ) { - bb_perror_msg("can't change %s of %s", "ownership", dest); - ret = EXIT_FAILURE; - } next: if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest); From vda.linux at googlemail.com Mon Oct 2 13:24:06 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 Oct 2023 15:24:06 +0200 Subject: [git commit] awk: implement -E; do not reorder -f and -e Message-ID: <20231002132435.CB5BF840ED@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=92ab29fcf04bc3ff3d3ad897f1c2463d8b8d1410 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta awk_main 843 891 +48 next_input_file 243 261 +18 packed_usage 34631 34638 +7 .rodata 105391 105390 -1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/1 up/down: 73/-1) Total: 72 bytes Signed-off-by: Denys Vlasenko --- editors/awk.c | 113 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/editors/awk.c b/editors/awk.c index efdff2778..bc95c4155 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -40,7 +40,7 @@ //usage:#define awk_full_usage "\n\n" //usage: " -v VAR=VAL Set variable" //usage: "\n -F SEP Use SEP as field separator" -//usage: "\n -f FILE Read program from FILE" +//usage: "\n -f/-E FILE Read program from FILE" //usage: IF_FEATURE_AWK_GNU_EXTENSIONS( //usage: "\n -e AWK_PROGRAM" //usage: ) @@ -76,8 +76,8 @@ * 1: -argz */ #define OPTSTR_AWK "+" \ - "F:v:*f:*" \ - IF_FEATURE_AWK_GNU_EXTENSIONS("e:*") \ + "F:v:f:" \ + IF_FEATURE_AWK_GNU_EXTENSIONS("e:E:") \ "W:" enum { OPTBIT_F, /* define field separator */ @@ -560,6 +560,7 @@ struct globals { var *Fields; char *g_pos; char g_saved_ch; + smallint got_program; smallint icase; smallint exiting; smallint nextrec; @@ -635,6 +636,7 @@ struct globals2 { #define Fields (G1.Fields ) #define g_pos (G1.g_pos ) #define g_saved_ch (G1.g_saved_ch ) +#define got_program (G1.got_program ) #define icase (G1.icase ) #define exiting (G1.exiting ) #define nextrec (G1.nextrec ) @@ -2899,11 +2901,13 @@ static int next_input_file(void) } fname = getvar_s(findvar(iamarray(intvar[ARGV]), utoa(argind))); if (fname && *fname) { - /* "If a filename on the command line has the form - * var=val it is treated as a variable assignment" - */ - if (try_to_assign(fname)) - continue; + if (got_program != 2) { /* there was no -E option */ + /* "If a filename on the command line has the form + * var=val it is treated as a variable assignment" + */ + if (try_to_assign(fname)) + continue; + } iF.F = xfopen_stdin(fname); setvar_i(intvar[ARGIND], argind); break; @@ -3659,13 +3663,7 @@ static int awk_exit(void) int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int awk_main(int argc UNUSED_PARAM, char **argv) { - unsigned opt; - char *opt_F; - llist_t *list_v = NULL; - llist_t *list_f = NULL; -#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS - llist_t *list_e = NULL; -#endif + int ch; int i; INIT_G(); @@ -3714,49 +3712,68 @@ int awk_main(int argc UNUSED_PARAM, char **argv) } } } - opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL); - argv += optind; - //argc -= optind; - if (opt & OPT_W) - bb_simple_error_msg("warning: option -W is ignored"); - if (opt & OPT_F) { - unescape_string_in_place(opt_F); - setvar_s(intvar[FS], opt_F); - } - while (list_v) { - if (!try_to_assign(llist_pop(&list_v))) - bb_show_usage(); - } - /* Parse all supplied programs */ fnhash = hash_init(); ahash = hash_init(); - while (list_f) { - int fd; - char *s; - g_progname = llist_pop(&list_f); - fd = xopen_stdin(g_progname); - s = xmalloc_read(fd, NULL); /* it's NUL-terminated */ - if (!s) - bb_perror_msg_and_die("read error from '%s'", g_progname); - close(fd); - parse_program(s); - free(s); - } - g_progname = "cmd. line"; + /* Cannot use getopt32: need to preserve order of -e / -f / -E / -i */ + while ((ch = getopt(argc, argv, OPTSTR_AWK)) >= 0) { + switch (ch) { + case 'F': + unescape_string_in_place(optarg); + setvar_s(intvar[FS], optarg); + break; + case 'v': + if (!try_to_assign(optarg)) + bb_show_usage(); + break; +//TODO: implement -i LIBRARY, it is easy-ish + case 'E': + case 'f': { + int fd; + char *s; + g_progname = optarg; + fd = xopen_stdin(g_progname); + s = xmalloc_read(fd, NULL); /* it's NUL-terminated */ + if (!s) + bb_perror_msg_and_die("read error from '%s'", g_progname); + close(fd); + parse_program(s); + free(s); + got_program = 1; + if (ch == 'E') { + got_program = 2; + goto stop_option_parsing; + } + break; + } #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS - while (list_e) { - parse_program(llist_pop(&list_e)); - } + case 'e': + g_progname = "cmd. line"; + parse_program(optarg); + got_program = 1; + break; #endif -//FIXME: preserve order of -e and -f -//TODO: implement -i LIBRARY and -E FILE too, they are easy-ish - if (!(opt & (OPT_f | OPT_e))) { + case 'W': + bb_simple_error_msg("warning: option -W is ignored"); + break; + default: +//bb_error_msg("ch:%d", ch); + bb_show_usage(); + } + } + stop_option_parsing: + + argv += optind; + //argc -= optind; + + if (!got_program) { if (!*argv) bb_show_usage(); + g_progname = "cmd. line"; parse_program(*argv++); } + /* Free unused parse structures */ //hash_free(fnhash); // ~250 bytes when empty, used only for function names //^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs From vda.linux at googlemail.com Tue Oct 3 17:16:10 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Tue, 3 Oct 2023 19:16:10 +0200 Subject: [git commit] syslogd: fix breakage caused by "daemonize _after_ init" change Message-ID: <20231003171638.AAA408410F@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=5fa39d48d53c7a3360d4f4da2c00232eb674678e branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master function old new delta syslogd_init 1007 1140 +133 create_socket 143 - -143 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/0 up/down: 133/-143) Total: -10 bytes Signed-off-by: Denys Vlasenko --- sysklogd/syslogd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 83b5c0cf6..7558051f0 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -956,9 +956,7 @@ static void do_mark(int sig) } #endif -/* Don't inline: prevent struct sockaddr_un to take up space on stack - * permanently */ -static NOINLINE int create_socket(void) +static int create_socket(void) { struct sockaddr_un sunx; int sock_fd; @@ -1008,6 +1006,7 @@ static int try_to_resolve_remote(remoteHost_t *rh) static int NOINLINE syslogd_init(char **argv) { int opts; + int fd; char OPTION_DECL; #if ENABLE_FEATURE_REMOTE_LOG llist_t *remoteAddrList = NULL; @@ -1055,7 +1054,7 @@ static int NOINLINE syslogd_init(char **argv) G.hostname = safe_gethostname(); *strchrnul(G.hostname, '.') = '\0'; - xmove_fd(create_socket(), STDIN_FILENO); + fd = create_socket(); if (opts & OPT_circularlog) ipcsyslog_init(); @@ -1067,6 +1066,8 @@ static int NOINLINE syslogd_init(char **argv) bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); } + xmove_fd(fd, STDIN_FILENO); + /* Set up signal handlers (so that they interrupt read()) */ signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo); signal_no_SA_RESTART_empty_mask(SIGINT, record_signo); From vda.linux at googlemail.com Wed Oct 4 14:46:35 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 4 Oct 2023 16:46:35 +0200 Subject: [git commit] udhcp: Avoid leaking uninitialized/stale data Message-ID: <20231004144659.19E68841F6@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=e265c8d4c039729f2a68f3b1fb589c13c38d86f8 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master I noticed a commit in connman: "gdhcp: Avoid leaking stack data via unitiialized variable" [1] Since gdhcp is just BusyBox udhcp with the serial numbers filed off, I checked if BusyBox udhcp has a related issue. The issue is that the get_option logic assumes any data within the memory area of the buffer is "valid". This reduces the complexity of the function at the cost of reading past the end of the actually received data in the case of specially crafted packets. This is not a problem for the udhcp_recv_kernel_packet data path as the entire memory area is zeroed. However, d4/d6_recv_raw_packet does not zero the memory. Note that a related commit [2] is not required as we are zeroing any data that can be read by the get_option function. [1] https://git.kernel.org/pub/scm/network/connman/connman.git/commit/?id=a74524b3e3fad81b0fd1084ffdf9f2ea469cd9b1 [2] https://git.kernel.org/pub/scm/network/connman/connman.git/commit/?id=58d397ba74873384aee449690a9070bacd5676fa function old new delta d4_recv_raw_packet 484 497 +13 d6_recv_raw_packet 216 228 +12 .rodata 105390 105381 -9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 25/-9) Total: 16 bytes Signed-off-by: Russ Dill Cc: Colin Wee Cc: Denys Vlasenko Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 1 + networking/udhcp/dhcpc.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index cdd06188e..a72fd31bd 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -961,6 +961,7 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_pac d6_dump_packet(&packet.data); bytes -= sizeof(packet.ip6) + sizeof(packet.udp); + memset(d6_pkt, 0, sizeof(*d6_pkt)); memcpy(d6_pkt, &packet.data, bytes); return bytes; } diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 200a2fb8a..07e2eadfe 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -966,7 +966,7 @@ static NOINLINE int d4_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) check = packet.udp.check; packet.udp.check = 0; if (check && check != inet_cksum(&packet, bytes)) { - log1s("packet with bad UDP checksum received, ignoring"); + log1s("packet with bad UDP checksum, ignoring"); return -2; } skip_udp_sum_check: @@ -981,6 +981,7 @@ static NOINLINE int d4_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) udhcp_dump_packet(&packet.data); bytes -= sizeof(packet.ip) + sizeof(packet.udp); + memset(dhcp_pkt, 0, sizeof(*dhcp_pkt)); memcpy(dhcp_pkt, &packet.data, bytes); return bytes; } From bugzilla at busybox.net Wed Oct 11 12:45:26 2023 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 11 Oct 2023 12:45:26 +0000 Subject: [Bug 15817] New: Inconsistent error reporting for modprobe -r Message-ID: https://bugs.busybox.net/show_bug.cgi?id=15817 Bug ID: 15817 Summary: Inconsistent error reporting for modprobe -r Product: Busybox Version: 1.35.x Hardware: All OS: Linux Status: NEW Severity: minor Priority: P5 Component: Networking Assignee: unassigned at busybox.net Reporter: bouwenwannes at gmail.com CC: busybox-cvs at busybox.net Target Milestone: --- Hello, I noticed an issue when removing modules that contain dependencies with modprobe -r. In do_modprobe (modutils/modprobe.c:416) we iterate through all items in m->deps. The first item is the module itself that we want to remove. Subsequent entries are modules that the current driver depends on. So, in the first iteration the variable first is set to 1 and an error is generated if we fail to remove the module (rc = bb_delete_module(m2->modname, O_EXCL);). After the first module, the variable first is set to 0 and we continue removing all the dependencies. If a dependency cannot be removed (with the same rc = bb_delete_module(m2->modname, O_EXCL); call), we ignore the return code and just continue to the next one. When the while loop exits, we in the end return rc (modutils/modprobe.c:508). Hence, the return code of the last dependency that we tried to remove is returned. This is in my opinion not correct. The last dependency could still be in use by another driver, which leads to a non-zero return code of bb_delete_module, while in practice there is no problem. I suggest following patch to always reset the return code to 0 for all the dependencies (so after first = 0) to get consistent error reporting. diff --git a/modutils/modprobe.c b/modutils/modprobe.c --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -462,6 +462,7 @@ static int do_modprobe(struct module_ent } /* do not error out if *deps* fail to unload */ first = 0; + rc = 0; continue; } Kind regards, Wannes -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Wed Oct 11 12:47:00 2023 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 11 Oct 2023 12:47:00 +0000 Subject: [Bug 15817] Inconsistent error reporting for modprobe -r In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=15817 bouwenwannes at gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Component|Networking |Other -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Fri Oct 13 11:06:50 2023 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 13 Oct 2023 11:06:50 +0000 Subject: [Bug 675] nslookup does not properly use second argument [SERVER] In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=675 --- Comment #12 from Gordon Lack --- This is still an issue in 1.36.1. Entware uses busybox and I have this installed on my Asus routers. This is the result of trying to specify a server [asus2]: nslookup birdman.dynalias.org 8.8.8.8 Server: 8.8.8.8 Address 1: 8.8.8.8 dns.google Name: birdman.dynalias.org Address 1: 192.168.1.240 birdman.dynalias.org but that address is from the local resolver (hence the local address) not the one from Google's resolvers. The correct answer (at the moment) is: [asus2]: host birdman.dynalias.org 8.8.8.8 Using domain server: Name: 8.8.8.8 Address: 8.8.8.8#53 Aliases: birdman.dynalias.org has address 92.16.225.130 It does read resolv.conf, but even moving that out of the way or replacing the nameserver line in there with 8.8.8.8 doesn't stop it using the local address. And that is because it is reading the local hosts file, even though a specific server is given. -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Thu Oct 26 14:08:57 2023 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Thu, 26 Oct 2023 14:08:57 +0000 Subject: [Bug 15829] New: Memory vulnerabilities in awk and sed Message-ID: https://bugs.busybox.net/show_bug.cgi?id=15829 Bug ID: 15829 Summary: Memory vulnerabilities in awk and sed Product: Busybox Version: unspecified Hardware: All OS: Linux Status: NEW Severity: critical Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: tuba at ece.ufl.edu CC: busybox-cvs at busybox.net Target Milestone: --- Hello, Our research group has found some exploitable vulnerabilities in BusyBox 1.36.0 using the AFL fuzzer. We used the defconfig as well as several configuration files generated by our own tool. We will provide all the details. However, we wonder if this is a secure channel to discuss the vulnerabilities. Please let us know. Thanks. Tuba -- You are receiving this mail because: You are on the CC list for the bug.