From matthewc at axis.com Mon Apr 1 13:54:07 2024 From: matthewc at axis.com (Matthew Chae) Date: Mon, 1 Apr 2024 15:54:07 +0200 Subject: fix large PID overflow their column in top command In-Reply-To: <55a05fe3-b60f-467a-9c71-084f8e6100d4@axis.com> References: <4458638ee54e4ae7a47a9586de9b874d@AcuMS.aculab.com> <20240213191635.624115f4@nbbrfq.loc> <20240215214614.0c6047ce@nbbrfq.loc> <20240221212303.11038f5e@nbbrfq.loc> <1fa111d8-6265-47e0-a0f7-2ffb5bbce8b4@axis.com> <55a05fe3-b60f-467a-9c71-084f8e6100d4@axis.com> Message-ID: On 3/1/24 12:53, Matthew Chae wrote: > On 3/1/24 12:36, Matthew Chae wrote: >> On 3/1/24 12:29, Matthew Chae wrote: >>> On 2/21/24 21:23, Bernhard Reutner-Fischer wrote: >>>> Hi Sukyoung! >>>> >>>> please don't top-post Hi Bernhard, I hope you are well. When you're available, can you give me feedback after reviewing the email I sent? >>>> >>>> On Mon, 19 Feb 2024 10:22:05 +0000 >>>> Matthew Chae wrote: >>>> >>>>> Hi Bernhard, >>>>> >>>>> I'm sending new patch and the result of bloatcheck. >>>>> For me, this size is reduced to 135 bytes. What do you think? >>>> >>>> Well, 135b is better than the initial 360b :) >>>> >>>>> Can you take a look at these attachments? >>>> >>>> I'd love to. >>>> But it doesn't apply, unfortunately: >>>> $ git am -s >>>> 0004-Allocate-PID-PPID-space-dynamically-in-top-command.patch >>>> Applying: Allocate PID/PPID space dynamically in top command >>>> error: patch failed: procps/top.c:637 >>>> error: procps/top.c: patch does not apply >>>> Patch failed at 0001 Allocate PID/PPID space dynamically in top command >>>> hint: Use 'git am --show-current-patch=diff' to see the failed patch >>>> When you have resolved this problem, run "git am --continue". >>>> If you prefer to skip this patch, run "git am --skip" instead. >>>> To restore the original branch and stop patching, run "git am --abort". >>>> $ git am --abort >>>> $ patch -p1 -i >>>> 0004-Allocate-PID-PPID-space-dynamically-in-top-command.patch >>>> patching file procps/top.c >>>> Hunk #1 FAILED at 637. >>>> Hunk #2 FAILED at 696. >>>> Hunk #3 FAILED at 709. >>>> 3 out of 3 hunks FAILED -- saving rejects to file procps/top.c.rej >>>> >>>> So I'd have to manually fiddle the patch to apply, which i honestly >>>> don't have time for ATM, as much as i love code-golf in general. >>>> >>> It?s very strange. Anyway, I'm sorry for causing you inconvenience. >>> At least now it shows successful results like below. >>> >>> git am -s 0005-Allocate-PID-PPID-space-dynamically-in-top-command.patch >>> Applying: Allocate PID/PPID space dynamically in top command >>> >>> Plus, the size is reduced more. It shows 115 bytes. You can check >>> this in the bloatcheck_result file. >>> >>>> Furthermore (and i'm about to update https://busybox.net/developer >>>> accordingly), for legal reasons, we require a Signed-off-by, as >>>> detailed in >>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html?highlight=sign%20off#sign-your-work-the-developer-s-certificate-of-origin >>>> so please check you legal department (which should be fine for axis) >>>> and mark your contributions accordingly by 'git commit -s ...' iff this >>>> is in line with your legal situation (again, axis legal will most >>>> likely understand what this is about without much further ado, AFAIK). >>> I already added this in the previous patch. Can you check the >>> attachment? If I'm missing something, please let me know. >>> >>>> >>>>> >>>>> PS: >>>>> The function of count_digits() is implemented inside of >>>>> display_process_list(). >>>>> To reduce the size, strlen() is not used. >>>> >>>> Did you look if manually outlining count_digits() like you did in the >>>> previous version is beneficial? >>>> >>> I don?t think outlining count_digits() is beneficial now. It appears >>> that, at least until now, there is no use case within BusyBox for >>> counting the digits of an integer variable. In terms of size as well, >>> using strlen() and utoa() as in the attached code appears to be more >>> advantageous. BTW, using make_human_readable_str() in the approach >>> you recommended does not seem appropriate for calculating the number >>> of digits. (pid_len = strlen(make_human_readable_str(pid_max,0,0)) >>> If I misunderstood, please let me know. >>> >>>> And, did you check my previous question if it is better to use the >>>> manual buf "painting", perusing in this case pid_len (for the >>>> compile-time constant 6 as it is now) and ppid_len (ditto), and, for >>>> your other patch on top, username_len (for the current compile-time >>>> constant 8)? The loop to determine the max {,p}pid len is not for free >>>> of course, so it's okish if that manifests size-wise. >>>> >>> When large numbers are assigned to PID and PPID, they occupy many >>> digits, leading to overflow in the PID and PPID columns. >>> Consequently, it becomes impossible to display the entire data >>> accurately and neatly. Additionally, a significant portion of the >>> user name may get truncated, providing very limited information about >>> the user name. By using this patch, although the loop is not for >>> free, it allows for the very accurate display of results from the top >>> command. Furthermore, the size is reduced to an appropriate level(115 >>> bytes), enabling very efficient results with minimal investment." >>> >>> Below is an example of how it can be improved. >>> Before: >>> ?? PID? PPID USER >>> 4876586 4394176 busy >>> >>> After: >>> ??? PID??? PPID USER >>> 4876548 4394517 busybox >> >> This example appears well-organized in Thunderbird as I intended, but >> it does not appear to be aligned properly in Outlook. If any >> recipients use Outlook to view this example, please ignore this example. >> > I apologize for the continued emails. When copying and pasting the > results from the command prompt into Thunderbird or Outlook, the example > appears much better organized than the actual result. In reality, the > 'Before' results of the 'top' command are much less organized than they > appear above. > >>> >>>> PS: 135b is better than the initial suggestion of ~300b, but given >>>> architectures tend to end up with very different codegen per arch and >>>> compilers used, i'm always curious which arch and which compiler >>>> (version) was used to obtain the alleged results. Guess you target >>>> chris with gcc-12-ish? >>>> Stating the target arch usually allows us a rough estimate >>>> about overall impact on other arches. >>> >>> I?m giving you the arch and compiler information below. >>> C Compiler: gcc -> gcc-10* >>> ARCH x86_64 >>> >>>> >>>> Many thanks in advance and cheers, >>>> Bernhard >>>> >>>>> >>>>> Br-Matthew >>>>> >>>>> ________________________________ >>>>> From: Bernhard Reutner-Fischer >>>>> Sent: Thursday, February 15, 2024 9:46 PM >>>>> To: Matthew Chae >>>>> Cc: rep.dot.nop at gmail.com ; David Laight >>>>> ; 'Denys Vlasenko' >>>>> ; busybox at busybox.net >>>>> ; Christopher Wong >>>>> Subject: Re: fix large PID overflow their column in top command >>>>> >>>>> On Wed, 14 Feb 2024 14:05:15 +0000 >>>>> Matthew Chae wrote: >>>>> >>>>>> Hi Bernhard, >>>>>> >>>>>> I'm sending new patch and the result of bloatcheck. >>>>> >>>>> Many thanks for the updated patch! >>>>> >>>>> function???????????????????????????????????????????? old???? new delta >>>>> display_process_list??????????????????????????????? 1406??? 1765 +359 >>>>> .rodata??????????????????????????????????????????? 99721 99724????? +3 >>>>> ------------------------------------------------------------------------------ >>>>> (add/remove: 0/0 grow/shrink: 2/0 up/down: 362/0) >>>>> Total: 362 bytes >>>>> ??? text??? data????? bss????? dec????? hex? filename >>>>> 1009548?? 16507???? 1840? 1027895?? faf37? busybox_old >>>>> 1009910?? 16507???? 1840? 1028257?? fb0a1 busybox_unstripped >>>>> >>>>> I think that's too much. For me this gives +293 bytes, still way >>>>> too much. >>>>> Can you please see if it helps to retain the manual formatting of >>>>> PID PPID USER? >>>>> >>>>> PS: >>>>> >>>>> procps/top.c: In function ?display_process_list?: >>>>> procps/top.c:664:1: warning: ISO C90 forbids mixed declarations and >>>>> code [-Wdeclaration-after-statement] >>>>> ?? 664 | typedef struct { unsigned quot, rem; } bb_div_t; >>>>> ?????? | ^~~~~~~ >>>>> >>>>> so please move your new #define PID_STR block down to right before >>>>> /* what info of the processes is shown */ >>>>> >>>>> In >>>>> +?????? int lines = (lines_rem - 1); >>>>> please drop the superfluous braces. >>>>> >>>>> It is most likely not smaller to use >>>>> pid_len = strlen(make_human_readable_str(pid_max,0,0)) >>>>> than to introduce this private count_digits(), i fear? >>>>> Maybe we could amortize the addition of count_digits by >>>>> reusing it elsewhere, as a follow-up. >>>>> >>>>> thanks >>>>> >>>>>> Can you review these and give me your thoughts? >>>>>> Just let me know if you think that the code size needs to be reduced. >>>>>> >>>>>> Br-Matthew >>>>>> ________________________________ >>>>>> From: Bernhard Reutner-Fischer >>>>>> Sent: Tuesday, February 13, 2024 7:16 PM >>>>>> To: Matthew Chae >>>>>> Cc: rep.dot.nop at gmail.com ; David Laight >>>>>> ; 'Denys Vlasenko' >>>>>> ; busybox at busybox.net >>>>>> ; Christopher Wong >>>>>> Subject: Re: fix large PID overflow their column in top command >>>>>> >>>>>> On Mon, 5 Feb 2024 09:56:20 +0000 >>>>>> Matthew Chae wrote: >>>>>> >>>>>>> Hi David, >>>>>>> >>>>>>> I'm sending an improved patch based on your comments. >>>>>>> >>>>>>> Not only does it not care about the PID_MAX value, >>>>>>> it searches all the contents to be output to recognize the >>>>>>> required column width >>>>>>> and dynamically allocates the space for PID and PPID >>>>>>> appropriately without creating a lot of empty space. >>>>>>> >>>>>>> Additionally, this patch still allows user names to be displayed >>>>>>> up to 8 characters without truncation. >>>>>>> >>>>>>> Can you look through the attachment? >>>>>> >>>>>> Unfortunately the patch does not apply to current master. >>>>>> How much would your patch add to the size? Can you bring it down to a >>>>>> minimum? >>>>>> See make baseline; apply the patch;make bloatcheck >>>>>> >>>>>> thanks >>>>>> >>>>>>> (0002-Allocate-PID-PPID-space-dynamically-in-top-command.patch) >>>>>>> >>>>>>> BR-Matthew Chae >>>>>>> ________________________________ >>>>>>> From: David Laight >>>>>>> Sent: Thursday, November 23, 2023 6:10 PM >>>>>>> To: 'Denys Vlasenko' ; Matthew Chae >>>>>>> >>>>>>> Cc: busybox at busybox.net ; Christopher Wong >>>>>>> >>>>>>> Subject: RE: fix large PID overflow their column in top command >>>>>>> >>>>>>> ... >>>>>>>> +?????? fp = xfopen_for_read("/proc/sys/kernel/pid_max"); >>>>>>>> +?????? if (!fgets(pid_buf, PID_DIGITS_MAX + 1, fp)) { >>>>>>>> ... >>>>>>>> +?????? if (strncmp(pid_buf, "32768", 5) == 0) >>>>>>>> +?????????????? pid_digits_num = 5; >>>>>>>> +?????? else >>>>>>>> +?????????????? pid_digits_num = PID_DIGITS_MAX; >>>>>>>> >>>>>>>> The logic above is not sound. Even if sysctl kernel.pid_max >>>>>>>> is 32768, there can be already running processes with pids > 99999. >>>>>>> >>>>>>> It's also probably wrong for pretty much all other values. >>>>>>> >>>>>>> I'd just base the column width on strlen(pid_buf) with a minimum >>>>>>> value of 5. >>>>>>> >>>>>>> It is unlikely that pid_max has been reduced - so column overflow >>>>>>> it that case probably doesn't really matter. >>>>>>> >>>>>>> The more interesting case is really a system with a very large >>>>>>> pid_max >>>>>>> that has never run many processes. >>>>>>> You don't really want lots of blank space. >>>>>>> >>>>>>> I can't remember whether top reads everything before doing any >>>>>>> output? >>>>>>> Since the output is sorted it probably almost always does. >>>>>>> In which case it knows the column width it will need. >>>>>>> >>>>>>> I did post a patch a while back that enabled 'Irix mode'. >>>>>>> (100% cpu is one cpu at 100%, not all cpus at 100%) >>>>>>> Maybe I should dig it out again. >>>>>>> >>>>>>> ???????? David >>>>>>> >>>>>>> - >>>>>>> Registered Address Lakeside, Bramley Road, Mount Farm, Milton >>>>>>> Keynes, MK1 1PT, UK >>>>>>> Registration No: 1397386 (Wales) >>>>>> >>>>> >>>> >> > From rmy at pobox.com Wed Apr 3 12:59:25 2024 From: rmy at pobox.com (Ron Yorston) Date: Wed, 03 Apr 2024 13:59:25 +0100 Subject: [PATCH] md5/shaXsum: accept uppercase hex strings Message-ID: <660d52ad.2eYOEoK6hhrSCda9%rmy@pobox.com> The coreutils versions of md5sum and the like accept uppercase hex strings from checksum files specified with the '-c' option. Use a case-insensitive comparison so BusyBox does the same. Signed-off-by: Ron Yorston --- coreutils/md5_sha1_sum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index f6a21237d..978d328f1 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c @@ -320,7 +320,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) hash_value = hash_file(in_buf, filename_ptr, sha3_width); - if (hash_value && (strcmp((char*)hash_value, line) == 0)) { + if (hash_value && (strcasecmp((char*)hash_value, line) == 0)) { if (!(flags & FLAG_SILENT)) printf("%s: OK\n", filename_ptr); } else { -- 2.44.0 From rmy at pobox.com Sat Apr 6 08:50:42 2024 From: rmy at pobox.com (Ron Yorston) Date: Sat, 06 Apr 2024 09:50:42 +0100 Subject: [PATCH] ash: move hashvar() calls into findvar() Message-ID: <66110ce2.v8pkviDE3pqtsGWp%rmy@pobox.com> dash has accepted a patch to remove the first argument of findvar(). It's commit e85e972 (var: move hashvar() calls into findvar()). Apply the same change to BusyBox ash. function old new delta findvar 35 40 +5 mklocal 268 261 -7 exportcmd 164 157 -7 setvareq 319 310 -9 lookupvar 150 141 -9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/4 up/down: 5/-32) Total: -27 bytes Signed-off-by: Ron Yorston --- shell/ash.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 4ca4c6c56..8195bfca3 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2328,9 +2328,11 @@ initvar(void) } static struct var ** -findvar(struct var **vpp, const char *name) +findvar(const char *name) { - for (; *vpp; vpp = &(*vpp)->next) { + struct var **vpp; + + for (vpp = hashvar(name); *vpp; vpp = &(*vpp)->next) { if (varcmp((*vpp)->var_text, name) == 0) { break; } @@ -2346,7 +2348,7 @@ lookupvar(const char *name) { struct var *v; - v = *findvar(hashvar(name), name); + v = *findvar(name); if (v) { #if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS /* @@ -2413,9 +2415,8 @@ setvareq(char *s, int flags) { struct var *vp, **vpp; - vpp = hashvar(s); flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1)); - vpp = findvar(vpp, s); + vpp = findvar(s); vp = *vpp; if (vp) { if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) { @@ -9967,7 +9968,6 @@ static void mklocal(char *name, int flags) { struct localvar *lvp; - struct var **vpp; struct var *vp; char *eq = strchr(name, '='); @@ -9996,8 +9996,7 @@ mklocal(char *name, int flags) lvp->text = memcpy(p, optlist, sizeof(optlist)); vp = NULL; } else { - vpp = hashvar(name); - vp = *findvar(vpp, name); + vp = *findvar(name); if (vp == NULL) { /* variable did not exist yet */ if (eq) @@ -14138,7 +14137,7 @@ exportcmd(int argc UNUSED_PARAM, char **argv) if (p != NULL) { p++; } else { - vp = *findvar(hashvar(name), name); + vp = *findvar(name); if (vp) { vp->flags = ((vp->flags | flag) & flag_off); continue; -- 2.44.0 From thomas.petazzoni at bootlin.com Sun Apr 7 17:18:44 2024 From: thomas.petazzoni at bootlin.com (Thomas Petazzoni) Date: Sun, 07 Apr 2024 17:18:44 -0000 Subject: Busybox hwclock failing to build with musl RISC-V 32-bit: SYS_settimeofday undefined Message-ID: <20240303153611.604aa33b@windsurf> Hello, The recently released musl 1.2.5 includes 32-bit RISC-V support. Turns out that building Busybox 1.36.1 with this new musl version, on 32-bit RISC-V, fails with: util-linux/hwclock.c: In function 'set_kernel_tz': util-linux/hwclock.c:142:27: error: 'SYS_settimeofday' undeclared (first use in this function); did you mean 'xsettimeofday'? 142 | int ret = syscall(SYS_settimeofday, NULL, tz); | ^~~~~~~~~~~~~~~~ | xsettimeofday util-linux/hwclock.c:142:27: note: each undeclared identifier is reported only once for each function it appears in Busybox already includes some slightly convoluted sorcery to deal with musl: static void set_kernel_tz(const struct timezone *tz) { #if LIBC_IS_MUSL /* musl libc does not pass tz argument to syscall * because "it's deprecated by POSIX, therefore it's fine * if we gratuitously break stuff" :( */ #if !defined(SYS_settimeofday) && defined(SYS_settimeofday_time32) # define SYS_settimeofday SYS_settimeofday_time32 #endif int ret = syscall(SYS_settimeofday, NULL, tz); #else int ret = settimeofday(NULL, tz); #endif if (ret) bb_simple_perror_msg_and_die("settimeofday"); } I am not sure whether this is a Busybox problem or a musl problem, which is why I'm cross-posting on both mailing lists. Thanks a lot in advance for your feedback, Thomas -- Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com From thomas.petazzoni at bootlin.com Sun Apr 7 17:18:48 2024 From: thomas.petazzoni at bootlin.com (Thomas Petazzoni) Date: Sun, 7 Apr 2024 19:18:48 +0200 Subject: Busybox hwclock failing to build with musl RISC-V 32-bit: SYS_settimeofday undefined Message-ID: <20240407191848.5c811765@windsurf> Hello, The recently released musl 1.2.5 includes 32-bit RISC-V support. Turns out that building Busybox 1.36.1 with this new musl version, on 32-bit RISC-V, fails with: util-linux/hwclock.c: In function 'set_kernel_tz': util-linux/hwclock.c:142:27: error: 'SYS_settimeofday' undeclared (first use in this function); did you mean 'xsettimeofday'? 142 | int ret = syscall(SYS_settimeofday, NULL, tz); | ^~~~~~~~~~~~~~~~ | xsettimeofday util-linux/hwclock.c:142:27: note: each undeclared identifier is reported only once for each function it appears in Busybox already includes some slightly convoluted sorcery to deal with musl: static void set_kernel_tz(const struct timezone *tz) { #if LIBC_IS_MUSL /* musl libc does not pass tz argument to syscall * because "it's deprecated by POSIX, therefore it's fine * if we gratuitously break stuff" :( */ #if !defined(SYS_settimeofday) && defined(SYS_settimeofday_time32) # define SYS_settimeofday SYS_settimeofday_time32 #endif int ret = syscall(SYS_settimeofday, NULL, tz); #else int ret = settimeofday(NULL, tz); #endif if (ret) bb_simple_perror_msg_and_die("settimeofday"); } I am not sure whether this is a Busybox problem or a musl problem, which is why I'm cross-posting on both mailing lists. Thanks a lot in advance for your feedback, Thomas -- Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com From rmy at pobox.com Mon Apr 8 12:12:25 2024 From: rmy at pobox.com (Ron Yorston) Date: Mon, 08 Apr 2024 13:12:25 +0100 Subject: [PATCH] timeout: allow fractional seconds in timeout values Message-ID: <6613df29.ZXgyiGsvwOS5oiJ0%rmy@pobox.com> The 'timeout' applet uses parse_duration_str() to obtain its timeout values. The default configuration enables float durations. However, the applet silently ignores fractional seconds. This results in unexpected behaviour: $ timeout 5.99 sleep 5.1; echo $? Terminated 143 When float durations are enabled ensure that any fractional seconds are taken into account. function old new delta timeout_wait 44 92 +48 timeout_main 383 365 -18 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 48/-18) Total: 30 bytes Signed-off-by: Ron Yorston --- coreutils/timeout.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/coreutils/timeout.c b/coreutils/timeout.c index 18aa9ebeb..84299a0a5 100644 --- a/coreutils/timeout.c +++ b/coreutils/timeout.c @@ -47,11 +47,16 @@ #include "libbb.h" -static NOINLINE int timeout_wait(int timeout, pid_t pid) +static NOINLINE int timeout_wait(duration_t timeout, pid_t pid) { /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */ while (1) { - sleep1(); +#if ENABLE_FLOAT_DURATION + if (timeout < 1) + sleep_for_duration(timeout); + else +#endif + sleep1(); if (--timeout <= 0) break; if (kill(pid, 0)) { @@ -68,8 +73,8 @@ int timeout_main(int argc UNUSED_PARAM, char **argv) int signo; int status; int parent = 0; - int timeout; - int kill_timeout; + duration_t timeout; + duration_t kill_timeout; pid_t pid; #if !BB_MMU char *sv1, *sv2; -- 2.44.0 From mikes at guam.net Mon Apr 8 22:04:34 2024 From: mikes at guam.net (Michael D. Setzer II) Date: Tue, 09 Apr 2024 08:04:34 +1000 Subject: Attempting to update to latest git get failure if TC command is set? Message-ID: <661469F2.19828.DEA21C3@mikes.guam.net> Have many times updated with no issues, but just tried, and build with TC options set it fails to compile. Manually go into .config and comment out the two lines with TC and then rerun make and it builds without issue. The git from 3/30 worked fine, but from 4/9 has error. My build machine in Guam, but am currently accessing it from Nevada, where I am taking care of mom.. +------------------------------------------------------------+ Michael D. Setzer II - Computer Science Instructor (Retired) mailto:mikes at guam.net mailto:msetzerii at gmail.com mailto:msetzerii at gmx.com Guam - Where America's Day Begins G4L Disk Imaging Project maintainer http://sourceforge.net/projects/g4l/ +------------------------------------------------------------+ From steffen at sdaoden.eu Mon Apr 8 23:01:07 2024 From: steffen at sdaoden.eu (steffen) Date: Tue, 09 Apr 2024 01:01:07 +0200 Subject: ash: support "set -m" monitor mode even when not interactive In-Reply-To: <20230117202731.6q006%steffen@sdaoden.eu> References: <20230117202731.6q006%steffen@sdaoden.eu> Message-ID: <20240408230107.DC94612D8D7@kent.sdaoden.eu> Hello. There was no answer to Steffen Nurpmeso wrote in <20230117202731.6q006%steffen at sdaoden.eu>: |This came up on the dash list, and so i took over Jilles |Tjoelker's FreeBSD commit from 2014 to busybox ash. |Note i have no idea of what i am doing, but from testing it seems |to work; i have simply taken it over, which is a cleanup really. |(This is on top of my arithmetic patch but it should not really |interfere, .. in case linenumber shifts are seen.) ... |From: Steffen Nurpmeso |Date: Tue, 17 Jan 2023 21:07:07 +0100 |Subject: [PATCH] ash: Allow enabling job control without a tty in | non-interactive mode.. | |This is a take-over of the FreeBSD bin/sh | | commit cd60e2c67d52e1f957841af19128c7227880743a | Author: Jilles Tjoelker | AuthorDate: 2014-09-04 21:48:33 +0000 | Commit: Jilles Tjoelker | CommitDate: 2014-09-04 21:48:33 +0000 | | sh: Allow enabling job control without a tty in non-interactive mode. | | If no tty is available, 'set -m' is still useful to put jobs \ | in their own | process groups. | |and makes a script of | | #!/bin/bash | #!/tmp/busybox ash | set -m | ( | echo >&2 "inner shell has: $(ps -o pid,pgid $$ | tail -n1)" | ) & | echo >&2 "outer shell has: $(ps -o pid,pgid $$ | tail -n1)" | echo >&2 "x is $$, job is $!: $(ps -o pid,pgid $! | tail -n1)" | |behave identical (including $(|) pipe races) when invoked in the |background via "./SCRIPT &". but Herbert Xu has coded another way to achieve the same for dash and likely soon commits it: Herbert Xu wrote in : ... |Thanks for the patch. I've rewritten it to minimise the impact. |However, the end result should be fairly similar. | |Please test this and let me know if there are any issues. (I see none. Maybe Ganael responds, too.) | |---8<--- |When a tty is unavailable, or the shell is in the background, |job control could still be used for the purpose of setting |process groups. | |This is based on work by Jilles Tjoelker from FreeBSD and Steffen |Nurpmeso. | |Reported-by: Steffen Nurpmeso |Reported-by: Ganael Laplanche |Signed-off-by: Herbert Xu | |diff --git a/src/jobs.c b/src/jobs.c |index a0f4d47..2a2fe22 100644 |--- a/src/jobs.c |+++ b/src/jobs.c |@@ -187,11 +187,21 @@ set_curjob(struct job *jp, unsigned mode) | | int jobctl; | |+static void xxtcsetpgrp(pid_t pgrp) |+{ |+ int fd = ttyfd; |+ |+ if (fd < 0) |+ return; |+ |+ xtcsetpgrp(fd, pgrp); |+} |+ | void | setjobctl(int on) | { |+ int pgrp = -1; | int fd; |- int pgrp; | | if (on == jobctl || rootshell == 0) | return; |@@ -207,36 +217,43 @@ setjobctl(int on) | fd = savefd(fd, ofd); | do { /* while we are in the background */ | if ((pgrp = tcgetpgrp(fd)) < 0) { |+close: |+ close(fd); |+ fd = -1; | out: |+ if (!iflag) |+ break; | sh_warnx("can't access tty; job control turned off"); | mflag = on = 0; |- goto close; |+ return; |} | if (pgrp == getpgrp()) | break; |+ if (!iflag) |+ goto close; | killpg(0, SIGTTIN); |} while (1); | initialpgrp = pgrp; |- |- setsignal(SIGTSTP); |- setsignal(SIGTTOU); |- setsignal(SIGTTIN); | pgrp = rootpid; |- setpgid(0, pgrp); |- xtcsetpgrp(fd, pgrp); |} else { | /* turning job control off */ | fd = ttyfd; | pgrp = initialpgrp; |- xtcsetpgrp(fd, pgrp); |- setpgid(0, pgrp); |- setsignal(SIGTSTP); |- setsignal(SIGTTOU); |- setsignal(SIGTTIN); |-close: |- close(fd); |- fd = -1; |} |+ |+ setsignal(SIGTSTP); |+ setsignal(SIGTTOU); |+ setsignal(SIGTTIN); |+ if (fd >= 0) { |+ setpgid(0, pgrp); |+ xtcsetpgrp(fd, pgrp); |+ |+ if (!on) { |+ close(fd); |+ fd = -1; |+ } |+ } |+ | ttyfd = fd; | jobctl = on; |} |@@ -391,7 +408,7 @@ restartjob(struct job *jp, int mode) | jp->state = JOBRUNNING; | pgid = jp->ps->pid; | if (mode == FORK_FG) |- xtcsetpgrp(ttyfd, pgid); |+ xxtcsetpgrp(pgid); | killpg(pgid, SIGCONT); | ps = jp->ps; | i = jp->nprocs; |@@ -874,7 +891,7 @@ static void forkchild(struct job *jp, union node \ |*n, int mode) | /* This can fail because we are doing it in the parent also */ | (void)setpgid(0, pgrp); | if (mode == FORK_FG) |- xtcsetpgrp(ttyfd, pgrp); |+ xxtcsetpgrp(pgrp); | setsignal(SIGTSTP); | setsignal(SIGTTOU); |} else |@@ -1014,7 +1031,7 @@ waitforjob(struct job *jp) | st = getstatus(jp); | #if JOBS | if (jp->jobctl) { |- xtcsetpgrp(ttyfd, rootpid); |+ xxtcsetpgrp(rootpid); | /* | * This is truly gross. | * If we're doing job control, then we did a TIOCSPGRP which |-- |Email: Herbert Xu |Home Page: http://gondor.apana.org.au/~herbert/ |PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt | --End of From mikes at guam.net Mon Apr 8 23:26:19 2024 From: mikes at guam.net (Michael D. Setzer II) Date: Tue, 09 Apr 2024 09:26:19 +1000 Subject: Attempting to update to latest git get failure if TC command is set? In-Reply-To: <661469F2.19828.DEA21C3@mikes.guam.net> References: <661469F2.19828.DEA21C3@mikes.guam.net> Message-ID: <66147D1B.20184.E34FB9D@mikes.guam.net> On 9 Apr 2024 at 8:04, Michael D. Setzer II wrote: From: "Michael D. Setzer II" To: busybox at busybox.net Date sent: Tue, 09 Apr 2024 08:04:34 +1000 Subject: Attempting to update to latest git get failure if TC command is set? Priority: normal Send reply to: mikes at guam.net > Have many times updated with no issues, but just tried, and build > with TC options set it fails to compile. > > Manually go into .config and comment out the two lines with TC > and then rerun make and it builds without issue. > > The git from 3/30 worked fine, but from 4/9 has error. > > My build machine in Guam, but am currently accessing it from > Nevada, where I am taking care of mom.. > These are the errors it gets if the two TC options are set in the .config. networking/tc.c: In function ?cbq_print_opt?: networking/tc.c:236:27: error: ?TCA_CBQ_MAX? undeclared (first use in this function); did you mean ?TCA_CBS_MAX?? 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; | ^~~~~~~~~~~ | TCA_CBS_MAX networking/tc.c:236:27: note: each undeclared identifier is reported only once for each function it appears in networking/tc.c:249:16: error: ?TCA_CBQ_RATE? undeclared (first use in this function); did you mean ?TCA_TBF_RATE64?? 249 | if (tb[TCA_CBQ_RATE]) { | ^~~~~~~~~~~~ | TCA_TBF_RATE64 networking/tc.c:255:16: error: ?TCA_CBQ_LSSOPT? undeclared (first use in this function) 255 | if (tb[TCA_CBQ_LSSOPT]) { | ^~~~~~~~~~~~~~ networking/tc.c:256:61: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_lssopt? 256 | if (RTA_PAYLOAD(tb[TCA_CBQ_LSSOPT]) < sizeof(*lss)) | ^ networking/tc.c:261:16: error: ?TCA_CBQ_WRROPT? undeclared (first use in this function) 261 | if (tb[TCA_CBQ_WRROPT]) { | ^~~~~~~~~~~~~~ networking/tc.c:262:61: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_wrropt? 262 | if (RTA_PAYLOAD(tb[TCA_CBQ_WRROPT]) < sizeof(*wrr)) | ^ networking/tc.c:267:16: error: ?TCA_CBQ_FOPT? undeclared (first use in this function) 267 | if (tb[TCA_CBQ_FOPT]) { | ^~~~~~~~~~~~ networking/tc.c:268:59: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_fopt? 268 | if (RTA_PAYLOAD(tb[TCA_CBQ_FOPT]) < sizeof(*fopt)) | ^ networking/tc.c:273:16: error: ?TCA_CBQ_OVL_STRATEGY? undeclared (first use in this function) 273 | if (tb[TCA_CBQ_OVL_STRATEGY]) { | ^~~~~~~~~~~~~~~~~~~~ networking/tc.c:274:67: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_ovl? 274 | if (RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(*ovl)) | ^ networking/tc.c:277:50: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_ovl? 277 | (unsigned) sizeof(*ovl)); | ^ networking/tc.c:293:23: error: invalid use of undefined type ?struct tc_cbq_lssopt? 293 | if (lss && lss->flags) { | ^~ networking/tc.c:296:24: error: invalid use of undefined type ?struct tc_cbq_lssopt? 296 | if (lss->flags&TCF_CBQ_LSS_BOUNDED) { | ^~ networking/tc.c:296:32: error: ?TCF_CBQ_LSS_BOUNDED? undeclared (first use in this function) 296 | if (lss->flags&TCF_CBQ_LSS_BOUNDED) { | ^~~~~~~~~~~~~~~~~~~ networking/tc.c:300:24: error: invalid use of undefined type ?struct tc_cbq_lssopt? 300 | if (lss->flags&TCF_CBQ_LSS_ISOLATED) { | ^~ networking/tc.c:300:32: error: ?TCF_CBQ_LSS_ISOLATED? undeclared (first use in this function) 300 | if (lss->flags&TCF_CBQ_LSS_ISOLATED) { | ^~~~~~~~~~~~~~~~~~~~ networking/tc.c:308:24: error: invalid use of undefined type ?struct tc_cbq_wrropt? 308 | if (wrr->priority != TC_CBQ_MAXPRIO) | ^~ networking/tc.c:308:38: error: ?TC_CBQ_MAXPRIO? undeclared (first use in this function) 308 | if (wrr->priority != TC_CBQ_MAXPRIO) | ^~~~~~~~~~~~~~ networking/tc.c:309:46: error: invalid use of undefined type ?struct tc_cbq_wrropt? 309 | printf("prio %u", wrr->priority); | ^~ networking/tc.c:313:43: error: invalid use of undefined type ?struct tc_cbq_wrropt? 313 | printf("/%u ", wrr->cpriority); | ^~ networking/tc.c:314:32: error: invalid use of undefined type ?struct tc_cbq_wrropt? 314 | if (wrr->weight != 1) { | ^~ networking/tc.c:315:65: error: invalid use of undefined type ?struct tc_cbq_wrropt? 315 | print_rate(buf, sizeof(buf), wrr->weight); | ^~ networking/tc.c:318:32: error: invalid use of undefined type ?struct tc_cbq_wrropt? 318 | if (wrr->allot) | ^~ networking/tc.c:319:57: error: invalid use of undefined type ?struct tc_cbq_wrropt? 319 | printf("allot %ub ", wrr->allot); | ^~ networking/tc.c:236:24: warning: unused variable ?tb? [-Wunused-variable] 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; | ^~ make[1]: *** [scripts/Makefile.build:198: networking/tc.o] Error 1 make: *** [Makefile:744: networking] Error 2 > > +------------------------------------------------------------+ > Michael D. Setzer II - Computer Science Instructor (Retired) > mailto:mikes at guam.net > mailto:msetzerii at gmail.com > mailto:msetzerii at gmx.com > Guam - Where America's Day Begins > G4L Disk Imaging Project maintainer > http://sourceforge.net/projects/g4l/ > +------------------------------------------------------------+ > > > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox +------------------------------------------------------------+ Michael D. Setzer II - Computer Science Instructor (Retired) mailto:mikes at guam.net mailto:msetzerii at gmail.com mailto:msetzerii at gmx.com Guam - Where America's Day Begins G4L Disk Imaging Project maintainer http://sourceforge.net/projects/g4l/ +------------------------------------------------------------+ From baruch at tkos.co.il Tue Apr 9 04:17:19 2024 From: baruch at tkos.co.il (Baruch Siach) Date: Tue, 09 Apr 2024 07:17:19 +0300 Subject: Attempting to update to latest git get failure if TC command is set? In-Reply-To: <66147D1B.20184.E34FB9D@mikes.guam.net> References: <661469F2.19828.DEA21C3@mikes.guam.net> <66147D1B.20184.E34FB9D@mikes.guam.net> Message-ID: <87h6gbmaj1.fsf@tarshish> Hi Michael, On Tue, Apr 09 2024, Michael D. Setzer II wrote: > On 9 Apr 2024 at 8:04, Michael D. Setzer II wrote: >> Have many times updated with no issues, but just tried, and build >> with TC options set it fails to compile. >> >> Manually go into .config and comment out the two lines with TC >> and then rerun make and it builds without issue. >> >> The git from 3/30 worked fine, but from 4/9 has error. >> >> My build machine in Guam, but am currently accessing it from >> Nevada, where I am taking care of mom.. > > These are the errors it gets if the two TC options are set in the > .config. > > networking/tc.c: In function ?cbq_print_opt?: > networking/tc.c:236:27: error: ?TCA_CBQ_MAX? undeclared (first use in this function); did you mean ?TCA_CBS_MAX?? > 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; > | ^~~~~~~~~~~ > | TCA_CBS_MAX See https://bugs.busybox.net/show_bug.cgi?id=15934 . baruch -- ~. .~ Tk Open Systems =}------------------------------------------------ooO--U--Ooo------------{= - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il - From mikes at guam.net Tue Apr 9 04:46:40 2024 From: mikes at guam.net (Michael D. Setzer II) Date: Tue, 09 Apr 2024 14:46:40 +1000 Subject: Attempting to update to latest git get failure if TC command is set? In-Reply-To: <87h6gbmaj1.fsf@tarshish> References: <661469F2.19828.DEA21C3@mikes.guam.net>, <66147D1B.20184.E34FB9D@mikes.guam.net>, <87h6gbmaj1.fsf@tarshish> Message-ID: <6614C830.11090.F5A44CC@mikes.guam.net> On 9 Apr 2024 at 7:17, Baruch Siach wrote: From: Baruch Siach To: mikes at guam.net Copies to: busybox at busybox.net Subject: Re: Attempting to update to latest git get failure if TC command is set? Date sent: Tue, 09 Apr 2024 07:17:19 +0300 > Hi Michael, > > On Tue, Apr 09 2024, Michael D. Setzer II wrote: > > On 9 Apr 2024 at 8:04, Michael D. Setzer II wrote: > >> Have many times updated with no issues, but just tried, and build > >> with TC options set it fails to compile. > >> > >> Manually go into .config and comment out the two lines with TC > >> and then rerun make and it builds without issue. > >> > >> The git from 3/30 worked fine, but from 4/9 has error. > >> > >> My build machine in Guam, but am currently accessing it from > >> Nevada, where I am taking care of mom.. > > > > These are the errors it gets if the two TC options are set in the > > .config. > > > > networking/tc.c: In function ?cbq_print_opt?: > > networking/tc.c:236:27: error: ?TCA_CBQ_MAX? undeclared (first use in this function); did you mean ?TCA_CBS_MAX?? > > 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; > > | ^~~~~~~~~~~ > > | TCA_CBS_MAX > > See https://bugs.busybox.net/show_bug.cgi?id=15934 . > > baruch > Didi the update again, and it prompted to add TC with the default as Y, so was added? Didn't have a link setup with TC, so removing it was no real issue. Just with make oldconfig answered N for the TC? Thanks for info. > -- > ~. .~ Tk Open Systems > =}------------------------------------------------ooO--U--Ooo------------{= > - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il - +------------------------------------------------------------+ Michael D. Setzer II - Computer Science Instructor (Retired) mailto:mikes at guam.net mailto:msetzerii at gmail.com mailto:msetzerii at gmx.com Guam - Where America's Day Begins G4L Disk Imaging Project maintainer http://sourceforge.net/projects/g4l/ +------------------------------------------------------------+ From rmy at pobox.com Tue Apr 9 08:50:59 2024 From: rmy at pobox.com (Ron Yorston) Date: Tue, 09 Apr 2024 09:50:59 +0100 Subject: [PATCH 1/2] libbb: use full_write1_str() to shrink busybox_main() Message-ID: <66150173.MXIbzXB/MRJvMLLn%rmy@pobox.com> There are two calls to dup2() in busybox_main(). These were introduced to coerce full_write2_str() into writing to stdout. The relevant commits were: 21278dff7 (busybox: do not print help to fd 2, print it to fd 1) and 5a7c72015 (busybox --list option. +140 bytes. Rob wanted it.) Later, in commit 729ecb87b (bbconfig: make it independent from printf functions), the function full_write1_str() was added. Using this in busybox_main() allows us to drop the dup2() calls. function old new delta run_applet_and_exit 796 760 -36 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-36) Total: -36 bytes Signed-off-by: Ron Yorston --- libbb/appletlib.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index d9cc48423..ad373ae1c 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -776,10 +776,9 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) help: output_width = get_terminal_width(2); - dup2(1, 2); - full_write2_str(bb_banner); /* reuse const string */ - full_write2_str(" multi-call binary.\n"); /* reuse */ - full_write2_str( + full_write1_str(bb_banner); /* reuse const string */ + full_write1_str(" multi-call binary.\n"); /* reuse */ + full_write1_str( "BusyBox is copyrighted by many authors between 1998-2015.\n" "Licensed under GPLv2. See source distribution for detailed\n" "copyright notices.\n" @@ -817,20 +816,20 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) while (*a) { int len2 = strlen(a) + 2; if (col >= (int)output_width - len2) { - full_write2_str(",\n"); + full_write1_str(",\n"); col = 0; } if (col == 0) { col = 6; - full_write2_str("\t"); + full_write1_str("\t"); } else { - full_write2_str(", "); + full_write1_str(", "); } - full_write2_str(a); + full_write1_str(a); col += len2; a += len2 - 1; } - full_write2_str("\n"); + full_write1_str("\n"); return 0; } @@ -850,14 +849,13 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) if (is_prefixed_with(argv[1], "--list")) { unsigned i = 0; const char *a = applet_names; - dup2(1, 2); while (*a) { # if ENABLE_FEATURE_INSTALLER if (argv[1][6]) /* --list-full? */ - full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); + full_write1_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); # endif - full_write2_str(a); - full_write2_str("\n"); + full_write1_str(a); + full_write1_str("\n"); i++; while (*a++ != '\0') continue; -- 2.44.0 From rmy at pobox.com Tue Apr 9 08:51:48 2024 From: rmy at pobox.com (Ron Yorston) Date: Tue, 09 Apr 2024 09:51:48 +0100 Subject: [PATCH 2/2] libbb: send usage messages to correct stream Message-ID: <661501a4.blIEQG27yp0v/CUk%rmy@pobox.com> POSIX generally requires normal output to go to stdout and diagnostic (i.e. error) output to go to stderr. When usage messages for BusyBox applets are specifically requested by the user (e.g. 'find --help') they should go to stdout; when they're emitted due to an error they should go to stderr. function old new delta bb_show_usage 148 146 -2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-2) Total: -2 bytes Signed-off-by: Avi Halachmi Signed-off-by: Ron Yorston --- libbb/appletlib.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index ad373ae1c..d2e5900b5 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -127,17 +127,19 @@ static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; void FAST_FUNC bb_show_usage(void) { if (ENABLE_SHOW_USAGE) { + ssize_t FAST_FUNC (*full_write_fn)(const char *) = + xfunc_error_retval ? full_write2_str : full_write1_str; #ifdef SINGLE_APPLET_STR /* Imagine that this applet is "true". Dont link in printf! */ const char *usage_string = unpack_usage_messages(); if (usage_string) { if (*usage_string == '\b') { - full_write2_str("No help available\n"); + full_write_fn("No help available\n"); } else { - full_write2_str("Usage: "SINGLE_APPLET_STR" "); - full_write2_str(usage_string); - full_write2_str("\n"); + full_write_fn("Usage: "SINGLE_APPLET_STR" "); + full_write_fn(usage_string); + full_write_fn("\n"); } if (ENABLE_FEATURE_CLEAN_UP) dealloc_usage_messages((char*)usage_string); @@ -153,19 +155,19 @@ void FAST_FUNC bb_show_usage(void) while (*p++) continue; ap--; } - full_write2_str(bb_banner); - full_write2_str(" multi-call binary.\n"); /* common string */ + full_write_fn(bb_banner); + full_write_fn(" multi-call binary.\n"); /* common string */ if (*p == '\b') - full_write2_str("\nNo help available\n"); + full_write_fn("\nNo help available\n"); else { - full_write2_str("\nUsage: "); - full_write2_str(applet_name); + full_write_fn("\nUsage: "); + full_write_fn(applet_name); if (p[0]) { if (p[0] != '\n') - full_write2_str(" "); - full_write2_str(p); + full_write_fn(" "); + full_write_fn(p); } - full_write2_str("\n"); + full_write_fn("\n"); } if (ENABLE_FEATURE_CLEAN_UP) dealloc_usage_messages((char*)usage_string); @@ -268,8 +270,10 @@ void lbb_prepare(const char *applet && !(ENABLE_TRUE && strcmp(applet_name, "true") == 0) && !(ENABLE_FALSE && strcmp(applet_name, "false") == 0) && !(ENABLE_ECHO && strcmp(applet_name, "echo") == 0) - ) + ) { + xfunc_error_retval = 0; bb_show_usage(); + } } #endif } -- 2.44.0 From palmer at rivosinc.com Wed Apr 10 00:23:01 2024 From: palmer at rivosinc.com (Palmer Dabbelt) Date: Tue, 9 Apr 2024 17:23:01 -0700 Subject: [PATCH] hwclock: Just give up on timezones for new ports Message-ID: <20240410002300.6957-2-palmer@rivosinc.com> As far as I can tell the kernel no longer suppports timezones on 32-bit ports without time32_t (ie, rv32). I have no idea what the right thing to do is here, but as far as I can tell all we can really do is to ignore the timezone. Signed-off-by: Palmer Dabbelt --- Sorry for the resend, I wasn't subscribed this morning so the mail bounced. --- util-linux/hwclock.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index e6f0043d0..597715de9 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c @@ -137,10 +137,24 @@ static void set_kernel_tz(const struct timezone *tz) * because "it's deprecated by POSIX, therefore it's fine * if we gratuitously break stuff" :( */ -#if !defined(SYS_settimeofday) && defined(SYS_settimeofday_time32) -# define SYS_settimeofday SYS_settimeofday_time32 -#endif +# if !defined(SYS_settimeofday) && defined(SYS_settimeofday_time32) +# define SYS_settimeofday SYS_settimeofday_time32 +# endif +# if defined(SYS_settimeofday) int ret = syscall(SYS_settimeofday, NULL, tz); +# else + /* Some new architectures have neither settimeofday nor + * settimeofday_time32, and the whole kernel timezone handling appears + * to have been dropped due to some oddities in the API. See: + * + * - glibc's commit c3f9aef063 ("Use clock_settime to implement settimeofday.") + * - https://github.com/systemd/systemd/issues/13305 + * - https://inbox.sourceware.org/libc-alpha/cb015d0d1d29e4b948c7118c5b12ff2bed83a6ec.1561421042.git.alistair.francis at wdc.com/ + * + * So instead just silently drop these calls. + */ + int ret = -ENOSYS; +# endif #else int ret = settimeofday(NULL, tz); #endif -- 2.44.0 From bjorn at rivosinc.com Wed Apr 10 06:06:49 2024 From: bjorn at rivosinc.com (=?UTF-8?B?QmrDtnJuIFTDtnBlbA==?=) Date: Wed, 10 Apr 2024 08:06:49 +0200 Subject: [PATCH] hwclock: Just give up on timezones for new ports In-Reply-To: <20240410002300.6957-2-palmer@rivosinc.com> References: <20240410002300.6957-2-palmer@rivosinc.com> Message-ID: On Wed, Apr 10, 2024 at 2:24?AM Palmer Dabbelt wrote: > > As far as I can tell the kernel no longer suppports timezones on 32-bit nit: "supports" > ports without time32_t (ie, rv32). I have no idea what the right thing > to do is here, but as far as I can tell all we can really do is to > ignore the timezone. > > Signed-off-by: Palmer Dabbelt > --- > Sorry for the resend, I wasn't subscribed this morning so the mail > bounced. My reply did as well! Let's retry -- now subscribed! :-D FWIW this fixes the riscv32/musl build for me, but the whole kernel/TZ workarounds seem a bit messy! :-) Thanks! buildroot/bb now says: | Welcome to Buildroot | buildroot login: root | # hwclock -s | hwclock: settimeofday: No such file or directory Tested-by: Bj?rn T?pel Reviewed-by: Bj?rn T?pel From Matthew.Chae at axis.com Wed Apr 10 10:37:12 2024 From: Matthew.Chae at axis.com (Matthew Chae) Date: Wed, 10 Apr 2024 10:37:12 +0000 Subject: Place option121 in DHCP request list based on RFC-3442 Message-ID: Hi maintainer, I?m submitting a patch for dhcpc that ensures compliance with RFC-3442. This patch addresses the following. The option 121(classless static route) in the DCHP request option has higher priority over the option3(router) and the option 33(classful static routes). This attached patch places the option121 before the option3 in the request list according to RFC-3442. Can I get your opinion for this? BR-Matthew Chae -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-dhcpc-place-option121-in-DHCP-request-list-based-on-.patch Type: text/x-patch Size: 1666 bytes Desc: 0001-dhcpc-place-option121-in-DHCP-request-list-based-on-.patch URL: From foo at mafoo.org.uk Wed Apr 10 15:44:57 2024 From: foo at mafoo.org.uk (Matthew Slowe) Date: Wed, 10 Apr 2024 15:44:57 +0000 Subject: "deprecated?" code causing chown to not support "." in username Message-ID: <9c1630ca6da94d61897a61d7383eeeeb6efe2159@mafoo.org.uk> In uidgid_get.c there is a parse_chown_usergroup_or_die() function which continues to implement a very old BSD(?) notation of user.group as well as user:group -- the code assumes that the first "." is a separater. I don't know what else calls it but, for the chown applet, the implementation precludes support of users with "."s in (such as "test.test") when invoked with "chown test.test file": # chown test.test /tmp/test chown: unknown user/group test:test https://github.com/mirror/busybox/blame/master/libpwdgrp/uidgid_get.c#L96 There is no reference to this interpretation in the code comment of the usage string: Usage: chown [-RhLHPcvf]... USER[:[GRP]] FILE... The best (dirtiest?) workaround for this appears to be: chown $(getent passwd test.test | cut -d: -f 3,4) /tmp/test Given that this notation appears to have been deprecated back in 2001, is now the time to remove this? -- Matthew From jody at jodybruchon.com Wed Apr 10 19:36:06 2024 From: jody at jodybruchon.com (Jody Bruchon) Date: Wed, 10 Apr 2024 15:36:06 -0400 Subject: [PATCH] Huge performance boost for recursion (cp, du, find, ls, rm, , mv) Message-ID: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> This patch uses pre-calculated name lengths to massively speed up various recursive operations. Three new *_fast variant functions are added along with get_d_namlen copied from libjodycode. Passing lengths allows use of memcpy() instead of strcpy()/strcat() and replacement of a particularly hot xasprintf(). Cachegrind shows CPU instructions on Linux x86_64 drop by 24% to 67% with similar reductions in data reads and writes. Anything in BusyBox that uses a while(readdir()) loop or that calls concat_*path_file() or last_char_is() might benefit from adopting this optimization framework. Bloat-O-Meter: function old???? new?? delta concat_path_file_fast -???? 194??? +194 get_d_namlen -????? 36???? +36 concat_subpath_file_fast -????? 31???? +31 last_char_is_fast -????? 26???? +26 complete_cmd_dir_file 992??? 1002???? +10 copy_file 1831??? 1834????? +3 remove_file 708???? 707????? -1 recursive_action1 420???? 419????? 0 du 468???? 467????? -1 scan_and_display_dirs_recur 675???? 672????? -3 concat_subpath_file 39?????? -???? -39 ------------------------------------------------------------------------------ (add/remove: 5/1 grow/shrink: 2/4 up/down: 300/-45)?????????? Total: 255 bytes Cachegrind tests (-original, +improved): -------------------------------------------------------------------------------- ??????????? Ir I1mr?????????? ILmr?????????? Dr???????????????? D1mr DLmr?????????? Dw???????????????? D1mw?????????? DLmw -------------------------------------------------------------------------------- cg_diff_cp:-1,811,369 (100.0%) 1,544 (100.0%) 1,514 (100.0%) 379,597 (100.0%) 3,151 (100.0%) 2,183 (100.0%) 249,874 (100.0%) 1,218 (100.0%) 1,160 (100.0%)? PROGRAM TOTALS cg_diff_cp:+1,310,239 (100.0%) 1,550 (100.0%) 1,519 (100.0%) 290,298 (100.0%) 3,152 (100.0%) 2,183 (100.0%) 184,883 (100.0%) 1,218 (100.0%) 1,160 (100.0%)? PROGRAM TOTALS cg_diff_du:-11,080,026 (100.0%) 1,692 (100.0%) 1,627 (100.0%) 2,345,969 (100.0%) 5,603 (100.0%) 2,524 (100.0%) 1,537,107 (100.0%) 1,838 (100.0%) 1,342 (100.0%) PROGRAM TOTALS cg_diff_du:+4,522,979 (100.0%) 1,635 (100.0%) 1,592 (100.0%) 1,189,256 (100.0%) 4,911 (100.0%) 2,513 (100.0%) 784,551 (100.0%) 1,636 (100.0%) 1,287 (100.0%)? PROGRAM TOTALS cg_diff_find:-10,719,682 (100.0%) 1,638 (100.0%) 1,592 (100.0%) 2,360,985 (100.0%) 4,149 (100.0%) 2,634 (100.0%) 1,493,014 (100.0%) 1,096 (100.0%) 836 (100.0%)? PROGRAM TOTALS cg_diff_find:+4,212,414 (100.0%) 1,527 (100.0%) 1,498 (100.0%) 1,215,858 (100.0%) 3,748 (100.0%) 2,629 (100.0%) 734,040 (100.0%) 850 (100.0%) 732 (100.0%)? PROGRAM TOTALS cg_diff_ls:-17,363,363 (100.0%) 1,984 (100.0%) 1,731 (100.0%) 3,751,223 (100.0%) 33,435 (100.0%) 2,439 (100.0%) 2,805,925 (100.0%) 9,422 (100.0%) 2,713 (100.0%) PROGRAM TOTALS cg_diff_ls:+11,166,139 (100.0%) 1,774 (100.0%) 1,683 (100.0%) 2,666,248 (100.0%) 31,111 (100.0%) 2,671 (100.0%) 2,100,224 (100.0%) 9,007 (100.0%) 2,474 (100.0%) PROGRAM TOTALS cg_diff_rm:-6,176,069 (100.0%) 1,585 (100.0%) 1,537 (100.0%) 1,298,524 (100.0%) 3,536 (100.0%) 2,351 (100.0%) 830,656 (100.0%) 905 (100.0%) 802 (100.0%)? PROGRAM TOTALS cg_diff_rm:+2,039,241 (100.0%) 1,459 (100.0%) 1,429 (100.0%) 573,877 (100.0%) 3,361 (100.0%) 2,438 (100.0%) 379,660 (100.0%) 724 (100.0%) 663 (100.0%)? PROGRAM TOTALS Signed-off-by: Jody Bruchon -------------- next part -------------- From 638521733744e1292ba2701c638983a2124761b2 Mon Sep 17 00:00:00 2001 From: Jody Bruchon Date: Wed, 10 Apr 2024 15:10:26 -0400 Subject: [PATCH] Huge performance boost for recursion (cp, du, find, ls, rm, mv) This patch uses pre-calculated name lengths to massively speed up various recursive operations. Three new *_fast variant functions are added along with get_d_namlen copied from libjodycode. Passing lengths allows use of memcpy() instead of strcpy()/strcat() and replacement of a particularly hot xasprintf(). Cachegrind shows CPU instructions on Linux x86_64 drop by 24% to 67% with similar reductions in data reads and writes. Anything in BusyBox that uses a while(readdir()) loop or that calls concat_*path_file() or last_char_is() might benefit from adopting this optimization framework. Bloat-O-Meter: function old new delta concat_path_file_fast - 194 +194 get_d_namlen - 36 +36 concat_subpath_file_fast - 31 +31 last_char_is_fast - 26 +26 complete_cmd_dir_file 992 1002 +10 copy_file 1831 1834 +3 remove_file 708 707 -1 recursive_action1 420 419 -1 du 468 467 -1 scan_and_display_dirs_recur 675 672 -3 concat_subpath_file 39 - -39 ------------------------------------------------------------------------------ (add/remove: 5/1 grow/shrink: 2/4 up/down: 300/-45) Total: 255 bytes Cachegrind tests (-original, +improved): -------------------------------------------------------------------------------- Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw -------------------------------------------------------------------------------- cg_diff_cp:-1,811,369 (100.0%) 1,544 (100.0%) 1,514 (100.0%) 379,597 (100.0%) 3,151 (100.0%) 2,183 (100.0%) 249,874 (100.0%) 1,218 (100.0%) 1,160 (100.0%) PROGRAM TOTALS cg_diff_cp:+1,310,239 (100.0%) 1,550 (100.0%) 1,519 (100.0%) 290,298 (100.0%) 3,152 (100.0%) 2,183 (100.0%) 184,883 (100.0%) 1,218 (100.0%) 1,160 (100.0%) PROGRAM TOTALS cg_diff_du:-11,080,026 (100.0%) 1,692 (100.0%) 1,627 (100.0%) 2,345,969 (100.0%) 5,603 (100.0%) 2,524 (100.0%) 1,537,107 (100.0%) 1,838 (100.0%) 1,342 (100.0%) PROGRAM TOTALS cg_diff_du:+4,522,979 (100.0%) 1,635 (100.0%) 1,592 (100.0%) 1,189,256 (100.0%) 4,911 (100.0%) 2,513 (100.0%) 784,551 (100.0%) 1,636 (100.0%) 1,287 (100.0%) PROGRAM TOTALS cg_diff_find:-10,719,682 (100.0%) 1,638 (100.0%) 1,592 (100.0%) 2,360,985 (100.0%) 4,149 (100.0%) 2,634 (100.0%) 1,493,014 (100.0%) 1,096 (100.0%) 836 (100.0%) PROGRAM TOTALS cg_diff_find:+4,212,414 (100.0%) 1,527 (100.0%) 1,498 (100.0%) 1,215,858 (100.0%) 3,748 (100.0%) 2,629 (100.0%) 734,040 (100.0%) 850 (100.0%) 732 (100.0%) PROGRAM TOTALS cg_diff_ls:-17,363,363 (100.0%) 1,984 (100.0%) 1,731 (100.0%) 3,751,223 (100.0%) 33,435 (100.0%) 2,439 (100.0%) 2,805,925 (100.0%) 9,422 (100.0%) 2,713 (100.0%) PROGRAM TOTALS cg_diff_ls:+11,166,139 (100.0%) 1,774 (100.0%) 1,683 (100.0%) 2,666,248 (100.0%) 31,111 (100.0%) 2,671 (100.0%) 2,100,224 (100.0%) 9,007 (100.0%) 2,474 (100.0%) PROGRAM TOTALS cg_diff_rm:-6,176,069 (100.0%) 1,585 (100.0%) 1,537 (100.0%) 1,298,524 (100.0%) 3,536 (100.0%) 2,351 (100.0%) 830,656 (100.0%) 905 (100.0%) 802 (100.0%) PROGRAM TOTALS cg_diff_rm:+2,039,241 (100.0%) 1,459 (100.0%) 1,429 (100.0%) 573,877 (100.0%) 3,361 (100.0%) 2,438 (100.0%) 379,660 (100.0%) 724 (100.0%) 663 (100.0%) PROGRAM TOTALS Signed-off-by: Jody Bruchon --- coreutils/du.c | 3 ++- coreutils/ls.c | 3 ++- include/libbb.h | 4 ++++ libbb/Kbuild.src | 1 + libbb/concat_path_file.c | 31 +++++++++++++++++++++++++++++++ libbb/concat_subpath_file.c | 8 ++++++++ libbb/copy_file.c | 3 ++- libbb/get_d_namlen.c | 29 +++++++++++++++++++++++++++++ libbb/last_char_is.c | 9 +++++++++ libbb/lineedit.c | 3 ++- libbb/recursive_action.c | 4 +++- libbb/remove_file.c | 3 ++- 12 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 libbb/get_d_namlen.c diff --git a/coreutils/du.c b/coreutils/du.c index 832dd75..e85b983 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -200,7 +200,8 @@ static unsigned long long du(const char *filename) } while ((entry = readdir(dir))) { - newfile = concat_subpath_file(filename, entry->d_name); +// newfile = concat_subpath_file(filename, entry->d_name); + newfile = concat_subpath_file_fast(filename, entry); if (newfile == NULL) continue; ++G.du_depth; diff --git a/coreutils/ls.c b/coreutils/ls.c index b69b804..ce3d1e5 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -949,7 +949,8 @@ static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p) continue; /* if only -A, skip . and .. but show other dotfiles */ } } - fullname = concat_path_file(path, entry->d_name); +// fullname = concat_path_file(path, entry->d_name); + fullname = concat_path_file_fast(path, entry); cur = my_stat(fullname, bb_basename(fullname), 0); if (!cur) { free(fullname); diff --git a/include/libbb.h b/include/libbb.h index cca33a1..2210256 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -563,6 +563,7 @@ char *bb_get_last_path_component_nostrip(const char *path) FAST_FUNC; const char *bb_basename(const char *name) FAST_FUNC; /* NB: can violate const-ness (similarly to strchr) */ char *last_char_is(const char *s, int c) FAST_FUNC; +char *last_char_is_fast(const char *s, int c, int len) FAST_FUNC; const char* endofname(const char *name) FAST_FUNC; char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; char *is_suffixed_with(const char *string, const char *key) FAST_FUNC; @@ -1671,9 +1672,12 @@ void config_close(parser_t *parser) FAST_FUNC; * If path is NULL, it is assumed to be "/". * filename should not be NULL. */ char *concat_path_file(const char *path, const char *filename) FAST_FUNC; +char *concat_path_file_fast(const char *path, const struct dirent *dirp) FAST_FUNC; /* Returns NULL on . and .. */ char *concat_subpath_file(const char *path, const char *filename) FAST_FUNC; +char *concat_subpath_file_fast(const char *path, const struct dirent *dirp) FAST_FUNC; +size_t get_d_namlen(const struct dirent * const dirent) FAST_FUNC; int bb_make_directory(char *path, long mode, int flags) FAST_FUNC; diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 653025e..8f601bd 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -39,6 +39,7 @@ lib-y += find_pid_by_name.o lib-y += find_root_device.o lib-y += full_write.o lib-y += get_console.o +lib-y += get_d_namlen.o lib-y += get_last_path_component.o lib-y += get_line_from_file.o lib-y += getpty.o diff --git a/libbb/concat_path_file.c b/libbb/concat_path_file.c index 5b4b7f1..2c6d57f 100644 --- a/libbb/concat_path_file.c +++ b/libbb/concat_path_file.c @@ -26,3 +26,34 @@ char* FAST_FUNC concat_path_file(const char *path, const char *filename) filename++; return xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename); } + + +char* FAST_FUNC concat_path_file_fast(const char *path, const struct dirent *dirp) +{ + const char *filename = dirp->d_name; + char *buf; + int lc_slash = 0; + int name_offset, end_offset; + int pathlen, namelen; + + if (!path) { + path = ""; + pathlen = 0; + } else pathlen = strlen(path); + namelen = get_d_namlen(dirp); + if (last_char_is_fast(path, '/', pathlen) == NULL) lc_slash = 1; + while (*filename == '/') { + filename++; + namelen--; + } + name_offset = pathlen + lc_slash; + end_offset = name_offset + namelen; + buf = (char *)malloc(end_offset + 1); + if (!buf) return NULL; + memcpy(buf, path, pathlen); + if (lc_slash == 1) *(buf + pathlen) = '/'; + memcpy((buf + name_offset), filename, namelen); + *(buf + end_offset) = '\0'; + return buf; +// return xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename); +} diff --git a/libbb/concat_subpath_file.c b/libbb/concat_subpath_file.c index bc2ee96..dc9c5fe 100644 --- a/libbb/concat_subpath_file.c +++ b/libbb/concat_subpath_file.c @@ -20,3 +20,11 @@ char* FAST_FUNC concat_subpath_file(const char *path, const char *f) return NULL; return concat_path_file(path, f); } + + +char* FAST_FUNC concat_subpath_file_fast(const char *path, const struct dirent *dirp) +{ + if (dirp->d_name && DOT_OR_DOTDOT(dirp->d_name)) + return NULL; + return concat_path_file_fast(path, dirp); +} diff --git a/libbb/copy_file.c b/libbb/copy_file.c index 044bc3c..b39b70e 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c @@ -197,7 +197,8 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) while ((d = readdir(dp)) != NULL) { char *new_source, *new_dest; - new_source = concat_subpath_file(source, d->d_name); +// new_source = concat_subpath_file(source, d->d_name); + new_source = concat_subpath_file_fast(source, d); if (new_source == NULL) continue; new_dest = concat_path_file(dest, d->d_name); diff --git a/libbb/get_d_namlen.c b/libbb/get_d_namlen.c new file mode 100644 index 0000000..1a9dbcf --- /dev/null +++ b/libbb/get_d_namlen.c @@ -0,0 +1,29 @@ +/* vi: set sw=4 ts=4: */ +/* + * Fast acquisition of d_namlen + * + * Copyright (C) 2024 by Jody Bruchon + * Copied from libjodycode for use with BusyBox + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#include "libbb.h" + +/* Extract d_namlen from struct dirent */ +size_t get_d_namlen(const struct dirent * const dirent) +{ +#ifdef _DIRENT_HAVE_D_NAMLEN + return dirent->d_namlen; +#elif defined _DIRENT_HAVE_D_RECLEN + const size_t base = (sizeof(struct dirent) - sizeof(((struct dirent *)0)->d_name)) - offsetof(struct dirent, d_name) - 1; + size_t skip; + + skip = dirent->d_reclen - (sizeof(struct dirent) - sizeof(((struct dirent *)0)->d_name)); + if (skip > 0) skip -= base; + return skip + strlen(dirent->d_name + skip); +#else + return strlen(dirent->d_name); +#endif + return 0; +} diff --git a/libbb/last_char_is.c b/libbb/last_char_is.c index fba05f9..30a4c5e 100644 --- a/libbb/last_char_is.c +++ b/libbb/last_char_is.c @@ -17,3 +17,12 @@ char* FAST_FUNC last_char_is(const char *s, int c) s++; return (*s == (char)c) ? (char *) s : NULL; } + + +/* Same as last_char_is() but uses a known length to skip the loop */ +char* FAST_FUNC last_char_is_fast(const char *s, int c, int len) +{ + if (len == 0) return NULL; + s += len - 1; + return (*s == (char)c) ? (char *) s : NULL; +} diff --git a/libbb/lineedit.c b/libbb/lineedit.c index c87d606..79dad06 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -918,7 +918,8 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) if (strncmp(basecmd, name_found, baselen) != 0) continue; /* no */ - found = concat_path_file(lpath, name_found); +// found = concat_path_file(lpath, name_found); + found = concat_path_file_fast(lpath, next); /* NB: stat() first so that we see is it a directory; * but if that fails, use lstat() so that * we still match dangling links */ diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c index b1c4bfa..54697f0 100644 --- a/libbb/recursive_action.c +++ b/libbb/recursive_action.c @@ -10,6 +10,7 @@ #undef DEBUG_RECURS_ACTION + /* * Walk down all the directories under the specified * location, and do something (something specified @@ -126,7 +127,8 @@ static int recursive_action1(recursive_state_t *state, const char *fileName) char *nextFile; int s; - nextFile = concat_subpath_file(fileName, next->d_name); +// nextFile = concat_subpath_file(fileName, next->d_name); + nextFile = concat_subpath_file_fast(fileName, next); if (nextFile == NULL) continue; diff --git a/libbb/remove_file.c b/libbb/remove_file.c index 1505e62..1cfe839 100644 --- a/libbb/remove_file.c +++ b/libbb/remove_file.c @@ -53,7 +53,8 @@ int FAST_FUNC remove_file(const char *path, int flags) while ((d = readdir(dp)) != NULL) { char *new_path; - new_path = concat_subpath_file(path, d->d_name); +// new_path = concat_subpath_file(path, d->d_name); + new_path = concat_subpath_file_fast(path, d); if (new_path == NULL) continue; if (remove_file(new_path, flags) < 0) -- 2.34.1 From dietmar.schindler at manrolandgoss.com Thu Apr 11 05:04:20 2024 From: dietmar.schindler at manrolandgoss.com (dietmar.schindler at manrolandgoss.com) Date: Thu, 11 Apr 2024 05:04:20 +0000 Subject: AW: [PATCH] Huge performance boost for recursion (cp, du, find, ls, rm, , mv) In-Reply-To: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> References: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> Message-ID: > Von: busybox Im Auftrag von Jody Bruchon > Gesendet: Mittwoch, 10. April 2024 21:36 > > Bloat-O-Meter: > > function old new delta > ? > recursive_action1 420 419 0 > ? How comes 419 - 420 = 0? -- Regards, Dietmar Schindler ________________________________ manroland Goss web systems GmbH | Managing Director: Franz Kriechbaum Registered Office: Augsburg | Trade Register: AG Augsburg | HRB-No.: 32609 | VAT: DE815764857 Confidentiality note: This message and any attached documents may contain confidential or proprietary information of manroland|Goss. These materials are intended only for the use of the intended recipient. If you are not the intended recipient of this transmission, you are hereby notified that any distribution, disclosure, printing, copying, storage, modification or the taking of any action in reliance upon this transmission is strictly prohibited. Delivery of this message to any person other than the intended recipient shall not compromise or waive such confidentiality, privilege or exemption from disclosure as to this communication. If you have received this communication in error, please immediately notify the sender and delete the message from your system. All liability for viruses is excluded to the fullest extent permitted by law. ________________________________ From eb at emlix.com Thu Apr 11 05:47:10 2024 From: eb at emlix.com (Rolf Eike Beer) Date: Thu, 11 Apr 2024 07:47:10 +0200 Subject: [PATCH] Huge performance boost for recursion (cp, du, find, ls, rm, , mv) In-Reply-To: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> References: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> Message-ID: <4911436.31r3eYUQgx@devpool47.emlix.com> On Mittwoch, 10. April 2024 21:36:06 CEST Jody Bruchon wrote: > This patch uses pre-calculated name lengths to massively speed up various > recursive operations. Three new *_fast variant functions are added along > with get_d_namlen copied from libjodycode. Passing lengths allows use of > memcpy() instead of strcpy()/strcat() and replacement of a particularly > hot xasprintf(). Cachegrind shows CPU instructions on Linux x86_64 drop > by 24% to 67% with similar reductions in data reads and writes. > > Anything in BusyBox that uses a while(readdir()) loop or that calls > concat_*path_file() or last_char_is() might benefit from adopting this > optimization framework. Completely untested, but how about this: char* FAST_FUNC concat_path_file_fast(const char *path, const struct dirent *dirp) { const char *filename = dirp->d_name; char *buf; int end_offset; int pathlen, namelen; if (!path) { path = ""; pathlen = 0; } else { pathlen = strlen(path); if (last_char_is_fast(path, '/', pathlen) == NULL) pathlen--; } namelen = get_d_namlen(dirp); while (*filename == '/') { filename++; namelen--; } end_offset = pathlen + 1 + namelen; buf = (char *)malloc(end_offset + 1); if (!buf) return NULL; memcpy(buf, path, pathlen); *(buf + pathlen) = '/'; memcpy(buf + pathlen + 1, filename, namelen); *(buf + end_offset) = '\0'; return buf; } This avoids scanning an empty path for the trailing slash, and avoids the check for a trailing slash later entirely, saving one instruction and 2 variables. You also have quite some places where you have the old code still around and just commented out, I would have just removed them. Generally I wonder if the length variables shouldn't be size_t or the like, which would not affect this function but all of them. Eike -- Besuchen Sie uns auf der Embedded World 2024 9. bis 11. April 2024 | Messe N?rnberg Sie finden uns in Halle 4, Stand 336 -- Rolf Eike Beer emlix GmbH Headquarters: Berliner Str. 12, 37073 G?ttingen, Germany Phone +49 (0)551 30664-0, e-mail info at emlix.com District Court of G?ttingen, Registry Number HR B 3160 Managing Directors: Heike Jordan, Dr. Uwe Kracke VAT ID No. DE 205 198 055 Office Berlin: Panoramastr. 1, 10178 Berlin, Germany Office Bonn: Bachstr. 6, 53115 Bonn, Germany http://www.emlix.com emlix - your embedded Linux partner -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 313 bytes Desc: This is a digitally signed message part. URL: From zhousiqi5 at huawei.com Fri Apr 12 07:09:19 2024 From: zhousiqi5 at huawei.com (zhousiqi (A)) Date: Fri, 12 Apr 2024 07:09:19 +0000 Subject: [Patch] udhcpc6: support generate a consistent iaid Message-ID: Currently, udhcpc6 does not meet the requirements for Identity Association in RFC 3315. This is a specific explanation of RFC 3315 protocol: https://datatracker.ietf.org/doc/html/rfc3315#section-10 "The IAID uniquely identifies the IA and must be chosen to be unique among the IAIDs on the client. The IAID is chosen by the client. For any given use of an IA by the client, the IAID for that IA MUST be consistent across restarts of the DHCP client." This patch allows the client to generate a consistent IAID based on the MAC address. Signed-off-by: Zhou Siqi --- networking/udhcp/d6_dhcpc.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index a35488d..99a53c8 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -741,6 +741,32 @@ static NOINLINE int send_d6_info_request(void) | OPTION_RECONF_ACCEPT | 0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ + +/*obtain a consistent IAID based on the MAC address*/ +static int d6_create_iaid() +{ + int data = 0; + int start_idx = 0, copy_len = 0; + int mac_len = 0; + + mac_len = sizeof(client_data.client_mac); + + /* + * A simple IAID is the last 4 bytes + * of the hardware address. + */ + if (mac_len > 4) { + start_idx = mac_len - 4; + copy_len = 4; + } else { + copy_len = mac_len; + } + + memcpy(&data, &client_data.client_mac[start_idx], copy_len); + + return data; +} + /* NOINLINE: limit stack usage in caller */ static NOINLINE int send_d6_discover(struct in6_addr *requested_ipv6) { @@ -759,7 +785,7 @@ static NOINLINE int send_d6_discover(struct in6_addr *requested_ipv6) client6_data.ia_na = xzalloc(len); client6_data.ia_na->code = D6_OPT_IA_NA; client6_data.ia_na->len = len - 4; - *(bb__aliased_uint32_t*)client6_data.ia_na->data = rand(); /* IAID */ + *(bb__aliased_uint32_t*)client6_data.ia_na->data = d6_create_iaid(); /* IAID */ if (requested_ipv6) { struct d6_option *iaaddr = (void*)(client6_data.ia_na->data + 4+4+4); iaaddr->code = D6_OPT_IAADDR; @@ -777,7 +803,7 @@ static NOINLINE int send_d6_discover(struct in6_addr *requested_ipv6) client6_data.ia_pd = xzalloc(len); client6_data.ia_pd->code = D6_OPT_IA_PD; client6_data.ia_pd->len = len - 4; - *(bb__aliased_uint32_t*)client6_data.ia_pd->data = rand(); /* IAID */ + *(bb__aliased_uint32_t*)client6_data.ia_pd->data = d6_create_iaid(); /* IAID */ opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, len); } From vda.linux at googlemail.com Sat Apr 13 16:00:08 2024 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sat, 13 Apr 2024 18:00:08 +0200 Subject: [PATCH] docproc: avoid segfault during file closing In-Reply-To: References: Message-ID: Applied, thank you. On Mon, Sep 11, 2023 at 6:03?PM Yan Zhu wrote: > > In the function find_export_symbols, since the fopen file does not > exit when it fails, there is a dereference problem in fclose(fp), > which will cause a segmentation fault. > > Signed-off-by: Yan Zhu > --- > scripts/basic/docproc.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c > index 4464e1874..8828901a1 100644 > --- a/scripts/basic/docproc.c > +++ b/scripts/basic/docproc.c > @@ -180,6 +180,7 @@ void find_export_symbols(char * filename) > { > fprintf(stderr, "docproc: "); > perror(real_filename); > + exit(1); > } > while (fgets(line, MAXLINESZ, fp)) { > unsigned char *p; > -- > 2.33.0 > > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From rasmus.villemoes at prevas.dk Mon Apr 15 12:56:23 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 15 Apr 2024 14:56:23 +0200 Subject: [PATCH 0/5] simplify and improve crypt_make_salt() Message-ID: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> Currently, crypt_make_salt() can only return 2^28 different salt strings. There are some low-hanging fruits allowing us to reduce the code size, and even with patch 5 which obviously by itself increases the footprint, the combined result of these patches is function old new delta crypt_make_salt 104 95 -9 i64c 41 24 -17 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-26) Total: -26 bytes while making sure (in the normal case where /dev/urandom is available) that the salt string is completely random, and that we are not in any case doing worse than what the current code does. Rasmus Villemoes (5): pw_encrypt.c: make i64c() slightly smaller crypt_make_salt: cleanup leftover comments crypt_make_salt(): simplify and improve crypt_make_salt(): fixup odd calling convention crypt_make_salt(): try to use actual random bytes for salt generation include/libbb.h | 11 ++--------- libbb/pw_encrypt.c | 27 +++++++++++---------------- networking/httpd.c | 2 +- 3 files changed, 14 insertions(+), 26 deletions(-) -- 2.40.1.1.g1c60b9335d From rasmus.villemoes at prevas.dk Mon Apr 15 12:56:24 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 15 Apr 2024 14:56:24 +0200 Subject: [PATCH 1/5] pw_encrypt.c: make i64c() slightly smaller In-Reply-To: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> Message-ID: <20240415125628.780178-2-rasmus.villemoes@prevas.dk> In ASCII at least, '.' is 0x2e, '/' is 0x2f and '0' is 0x30. So the existing "if (i < 12)" case does the right thing also for i <= 1. I don't know if busybox supports anything but ASCII environments, but since we can do it build-time with preprocessor conditionals, we might as well leave the two cases in the code, which then (along with the terse comment) also serves as a bit of explanation for what the i<12 case then ends up producing. function old new delta i64c 41 24 -17 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-17) Total: -17 bytes Signed-off-by: Rasmus Villemoes --- libbb/pw_encrypt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 3463fd95b..adbdc1d1e 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -20,10 +20,13 @@ static int i64c(int i) { i &= 0x3f; + /* In ascii, '.', '/' and '0' are consecutive. */ +#if '0' - 2 != '.' || '0' - 1 != '/' if (i == 0) return '.'; if (i == 1) return '/'; +#endif if (i < 12) return ('0' - 2 + i); if (i < 38) -- 2.40.1.1.g1c60b9335d From rasmus.villemoes at prevas.dk Mon Apr 15 12:56:25 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 15 Apr 2024 14:56:25 +0200 Subject: [PATCH 2/5] crypt_make_salt: cleanup leftover comments In-Reply-To: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> Message-ID: <20240415125628.780178-3-rasmus.villemoes@prevas.dk> Way back in commit 12a432715f06, crypt_make_salt() was changed to use monotonic_us() instead of time(NULL) as a poor man's random source, and, since that then at least made it much less likely that consecutive calls would return the same result, at the same time lost the "rnd" parameter. Remnants of that were left in comments, but 13 years later that really serves no purpose. Signed-off-by: Rasmus Villemoes --- include/libbb.h | 11 ++--------- libbb/pw_encrypt.c | 3 +-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index ef5d04713..db61e62ab 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1783,15 +1783,8 @@ int ask_and_check_password(const struct passwd *pw) FAST_FUNC; #endif extern char *pw_encrypt(const char *clear, const char *salt, int cleanup) FAST_FUNC; extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC; -/* - * rnd is additional random input. New one is returned. - * Useful if you call crypt_make_salt many times in a row: - * rnd = crypt_make_salt(buf1, 4, 0); - * rnd = crypt_make_salt(buf2, 4, rnd); - * rnd = crypt_make_salt(buf3, 4, rnd); - * (otherwise we risk having same salt generated) - */ -extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC; + +extern int crypt_make_salt(char *p, int cnt) FAST_FUNC; /* "$N$" + sha_salt_16_bytes + NUL */ #define MAX_PW_SALT_LEN (3 + 16 + 1) extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC; diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index adbdc1d1e..458792faa 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -34,9 +34,8 @@ static int i64c(int i) return ('a' - 38 + i); } -int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) +int FAST_FUNC crypt_make_salt(char *p, int cnt) { - /* was: x += ... */ unsigned x = getpid() + monotonic_us(); do { /* x = (x*1664525 + 1013904223) % 2^32 generator is lame -- 2.40.1.1.g1c60b9335d From rasmus.villemoes at prevas.dk Mon Apr 15 12:56:26 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 15 Apr 2024 14:56:26 +0200 Subject: [PATCH 3/5] crypt_make_salt(): simplify and improve In-Reply-To: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> Message-ID: <20240415125628.780178-4-rasmus.villemoes@prevas.dk> The use of a PRNG here is useless. No matter what, the generated salt string is completely determined by the initial value of x. In fact, since we only look at bits 16-27 and it's a LCG with a power-of-2 modulus (so the high bits never affect lower bits), only 2^28 different salts can be produced. So instead of pretending to generate a random string, just base64-encode the bits we actually have, and make sure all of them are used. That way we can produce 2^32 instead of 2^28 different salts, and it also becomes more transparent (due to the trailing '.' characters from when x hits 0) that the salt generation is not particularly thorough. Signed-off-by: Rasmus Villemoes --- libbb/pw_encrypt.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 458792faa..9ac75b281 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -37,18 +37,11 @@ static int i64c(int i) int FAST_FUNC crypt_make_salt(char *p, int cnt) { unsigned x = getpid() + monotonic_us(); + /* Odd calling convention... */ + cnt *= 2; do { - /* x = (x*1664525 + 1013904223) % 2^32 generator is lame - * (low-order bit is not "random", etc...), - * but for our purposes it is good enough */ - x = x*1664525 + 1013904223; - /* BTW, Park and Miller's "minimal standard generator" is - * x = x*16807 % ((2^31)-1) - * It has no problem with visibly alternating lowest bit - * but is also weak in cryptographic sense + needs div, - * which needs more code (and slower) on many CPUs */ - *p++ = i64c(x >> 16); - *p++ = i64c(x >> 22); + *p++ = i64c(x); + x >>= 6; } while (--cnt); *p = '\0'; return x; -- 2.40.1.1.g1c60b9335d From rasmus.villemoes at prevas.dk Mon Apr 15 12:56:27 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 15 Apr 2024 14:56:27 +0200 Subject: [PATCH 4/5] crypt_make_salt(): fixup odd calling convention In-Reply-To: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> Message-ID: <20240415125628.780178-5-rasmus.villemoes@prevas.dk> Due to the implementation of crypt_make_salt(), it used to make sense that the length parameter was only half of the expected length of the salt, but that's not so any more, so clean it up and make the callers pass the desired length directly. Signed-off-by: Rasmus Villemoes --- libbb/pw_encrypt.c | 8 +++----- networking/httpd.c | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 9ac75b281..3de31f711 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -37,8 +37,6 @@ static int i64c(int i) int FAST_FUNC crypt_make_salt(char *p, int cnt) { unsigned x = getpid() + monotonic_us(); - /* Odd calling convention... */ - cnt *= 2; do { *p++ = i64c(x); x >>= 6; @@ -49,21 +47,21 @@ int FAST_FUNC crypt_make_salt(char *p, int cnt) char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) { - int len = 2/2; + int len = 2; char *salt_ptr = salt; /* Standard chpasswd uses uppercase algos ("MD5", not "md5"). * Need to be case-insensitive in the code below. */ if ((algo[0]|0x20) != 'd') { /* not des */ - len = 8/2; /* so far assuming md5 */ + len = 8; /* so far assuming md5 */ *salt_ptr++ = '$'; *salt_ptr++ = '1'; *salt_ptr++ = '$'; #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA if ((algo[0]|0x20) == 's') { /* sha */ salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); - len = 16/2; + len = 16; } #endif } diff --git a/networking/httpd.c b/networking/httpd.c index ddcb03bca..825a87d81 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -2826,7 +2826,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) salt[0] = '$'; salt[1] = '1'; salt[2] = '$'; - crypt_make_salt(salt + 3, 4); + crypt_make_salt(salt + 3, 8); puts(pw_encrypt(pass, salt, /*cleanup:*/ 0)); return 0; } -- 2.40.1.1.g1c60b9335d From rasmus.villemoes at prevas.dk Mon Apr 15 12:56:28 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 15 Apr 2024 14:56:28 +0200 Subject: [PATCH 5/5] crypt_make_salt(): try to use actual random bytes for salt generation In-Reply-To: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> Message-ID: <20240415125628.780178-6-rasmus.villemoes@prevas.dk> Instead of limiting the possible generated salts to 2^32 different ones, try to get some actual random bits and mix those in. Keep the old pseudo-random generation in place, so that even if open_read_close() fails or only returns a partial result, we're not doing any worse than previously. In fact, even with /dev/urandom being unavailable, this might still improve things a bit since whatever sort-of random content might be in the p buffer on entry is then mixed in. Signed-off-by: Rasmus Villemoes --- libbb/pw_encrypt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 3de31f711..cbb1f36f0 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -37,8 +37,10 @@ static int i64c(int i) int FAST_FUNC crypt_make_salt(char *p, int cnt) { unsigned x = getpid() + monotonic_us(); + open_read_close("/dev/urandom", p, cnt); do { - *p++ = i64c(x); + *p = i64c(x + *p); + p++; x >>= 6; } while (--cnt); *p = '\0'; -- 2.40.1.1.g1c60b9335d From jody at jodybruchon.com Mon Apr 15 15:14:11 2024 From: jody at jodybruchon.com (Jody Bruchon) Date: Mon, 15 Apr 2024 11:14:11 -0400 Subject: [PATCH] Huge performance boost for recursion (cp, du, find, ls, rm, , mv) In-Reply-To: <4911436.31r3eYUQgx@devpool47.emlix.com> References: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> <4911436.31r3eYUQgx@devpool47.emlix.com> Message-ID: <3a631be6-f7dd-0c0a-c1ba-9cef8b6a375c@jodybruchon.com> With these changes, 'busybox find .' and 'busybox find libbb' fail entirely, with 'libbb' becoming 'libb' instead. Running 'busybox find libbb/' works but the result has double-slashes: 'libbb//whatever.c'. The last char of the parameter passed to 'find' is being erased if there is no slash. I left the old code commented instead of taking it out because there is a good chance the maintainers will want to see this "bloat" gated behind a config option. On 2024-04-11 1:47 AM, Rolf Eike Beer wrote: > On Mittwoch, 10. April 2024 21:36:06 CEST Jody Bruchon wrote: >> This patch uses pre-calculated name lengths to massively speed up various >> recursive operations. Three new *_fast variant functions are added along >> with get_d_namlen copied from libjodycode. Passing lengths allows use of >> memcpy() instead of strcpy()/strcat() and replacement of a particularly >> hot xasprintf(). Cachegrind shows CPU instructions on Linux x86_64 drop >> by 24% to 67% with similar reductions in data reads and writes. >> >> Anything in BusyBox that uses a while(readdir()) loop or that calls >> concat_*path_file() or last_char_is() might benefit from adopting this >> optimization framework. > Completely untested, but how about this: > > char* FAST_FUNC concat_path_file_fast(const char *path, const struct dirent > *dirp) > { > const char *filename = dirp->d_name; > char *buf; > int end_offset; > int pathlen, namelen; > > if (!path) { > path = ""; > pathlen = 0; > } else { > pathlen = strlen(path); > if (last_char_is_fast(path, '/', pathlen) == NULL) > pathlen--; > } > namelen = get_d_namlen(dirp); > while (*filename == '/') { > filename++; > namelen--; > } > end_offset = pathlen + 1 + namelen; > buf = (char *)malloc(end_offset + 1); > if (!buf) return NULL; > memcpy(buf, path, pathlen); > *(buf + pathlen) = '/'; > memcpy(buf + pathlen + 1, filename, namelen); > *(buf + end_offset) = '\0'; > return buf; > } > > This avoids scanning an empty path for the trailing slash, and avoids the > check for a trailing slash later entirely, saving one instruction and 2 > variables. > > You also have quite some places where you have the old code still around and > just commented out, I would have just removed them. > > Generally I wonder if the length variables shouldn't be size_t or the like, > which would not affect this function but all of them. > > Eike From steffen at sdaoden.eu Mon Apr 15 19:05:25 2024 From: steffen at sdaoden.eu (Steffen Nurpmeso) Date: Mon, 15 Apr 2024 21:05:25 +0200 Subject: [PATCH 5/5] crypt_make_salt(): try to use actual random bytes for salt generation In-Reply-To: <20240415125628.780178-6-rasmus.villemoes@prevas.dk> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> <20240415125628.780178-6-rasmus.villemoes@prevas.dk> Message-ID: <20240415190525.Zku33-4H@steffen%sdaoden.eu> Rasmus Villemoes wrote in <20240415125628.780178-6-rasmus.villemoes at prevas.dk>: |Instead of limiting the possible generated salts to 2^32 different |ones, try to get some actual random bits and mix those in. Keep the |old pseudo-random generation in place, so that even if |open_read_close() fails or only returns a partial result, we're not |doing any worse than previously. | |In fact, even with /dev/urandom being unavailable, this might still |improve things a bit since whatever sort-of random content might be in |the p buffer on entry is then mixed in. By that time i thought (completely unrelated with your work) that the code from miscutils/seedrng.c which has a more broad view of where to get random data from should possibly be generalized. There are more than just one match for /dev/urandom, and they all want some random bits. --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) From jody at jodybruchon.com Tue Apr 16 02:10:17 2024 From: jody at jodybruchon.com (Jody Bruchon) Date: Mon, 15 Apr 2024 22:10:17 -0400 (EDT) Subject: [PATCH v2] Huge performance boost for recursion (cp, du, find, ls, rm, mv) In-Reply-To: <3a631be6-f7dd-0c0a-c1ba-9cef8b6a375c@jodybruchon.com> References: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> <4911436.31r3eYUQgx@devpool47.emlix.com> <3a631be6-f7dd-0c0a-c1ba-9cef8b6a375c@jodybruchon.com> Message-ID: <1121476545.8164395.1713233417421@email.ionos.com> This revision reduces code size in concat_path_file_fast() by 19 bytes. It also applies the new get_d_namlen() optimization to a readdir() loop in runit/svlogd.c. If there are any changes that need to be made for inclusion then please let me know as soon as possible. I'd like to finish this project up. If the old/slow and new/fast code should be chosen with a compile-time config option then I'm happy to do that as well. -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-Huge-performance-boost-for-recursion-cp-du-find-l.patch Type: text/x-patch Size: 13982 bytes Desc: not available URL: From rasmus.villemoes at prevas.dk Tue Apr 16 06:31:31 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Tue, 16 Apr 2024 08:31:31 +0200 Subject: [PATCH 5/5] crypt_make_salt(): try to use actual random bytes for salt generation In-Reply-To: <20240415190525.Zku33-4H@steffen%sdaoden.eu> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> <20240415125628.780178-6-rasmus.villemoes@prevas.dk> <20240415190525.Zku33-4H@steffen%sdaoden.eu> Message-ID: On 15/04/2024 21.05, Steffen Nurpmeso wrote: > Rasmus Villemoes wrote in > <20240415125628.780178-6-rasmus.villemoes at prevas.dk>: > |Instead of limiting the possible generated salts to 2^32 different > |ones, try to get some actual random bits and mix those in. Keep the > |old pseudo-random generation in place, so that even if > |open_read_close() fails or only returns a partial result, we're not > |doing any worse than previously. > | > |In fact, even with /dev/urandom being unavailable, this might still > |improve things a bit since whatever sort-of random content might be in > |the p buffer on entry is then mixed in. > > By that time i thought (completely unrelated with your work) that > the code from miscutils/seedrng.c which has a more broad view of > where to get random data from should possibly be generalized. > There are more than just one match for /dev/urandom, and they all > want some random bits. Yeah, I know, I did go grepping for 'random' to see if bb already had some "gimme some random bytes" helper, and I've also sort-of followed the seedrng saga. But since there was no such helper, and just best-effort here is good enough for a significant improvement in the normal case, I just went with the oneliner open_read_close(), which is also used in generate_uuid() without checking the return value. If some common infrastructure for randomness should materialize, this can trivially be switched over. But I really didn't want to tie this series to creation of and bikeshedding over such infrastructure. Rasmus From eb at emlix.com Tue Apr 16 06:59:22 2024 From: eb at emlix.com (Rolf Eike Beer) Date: Tue, 16 Apr 2024 08:59:22 +0200 Subject: [PATCH] Huge performance boost for recursion (cp, du, find, ls, rm, , mv) In-Reply-To: <3a631be6-f7dd-0c0a-c1ba-9cef8b6a375c@jodybruchon.com> References: <2cfc6093-9eb9-d71b-6844-c7255639b61e@jodybruchon.com> <4911436.31r3eYUQgx@devpool47.emlix.com> <3a631be6-f7dd-0c0a-c1ba-9cef8b6a375c@jodybruchon.com> Message-ID: <4912893.31r3eYUQgx@devpool47.emlix.com> On Montag, 15. April 2024 17:14:11 MESZ Jody Bruchon wrote: > With these changes, 'busybox find .' and 'busybox find libbb' fail > entirely, with 'libbb' becoming 'libb' instead. Running 'busybox find > libbb/' works but the result has double-slashes: 'libbb//whatever.c'. > The last char of the parameter passed to 'find' is being erased if there > is no slash. This line is wrong: > if (last_char_is_fast(path, '/', pathlen) == NULL) pathlen--; If you replace "==" with "!=" it works. Regard, Eike -- Rolf Eike Beer emlix GmbH Headquarters: Berliner Str. 12, 37073 G?ttingen, Germany Phone +49 (0)551 30664-0, e-mail info at emlix.com District Court of G?ttingen, Registry Number HR B 3160 Managing Directors: Heike Jordan, Dr. Uwe Kracke VAT ID No. DE 205 198 055 Office Berlin: Panoramastr. 1, 10178 Berlin, Germany Office Bonn: Bachstr. 6, 53115 Bonn, Germany http://www.emlix.com emlix - your embedded Linux partner -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 313 bytes Desc: This is a digitally signed message part. URL: From steffen at sdaoden.eu Tue Apr 16 18:00:25 2024 From: steffen at sdaoden.eu (Steffen Nurpmeso) Date: Tue, 16 Apr 2024 20:00:25 +0200 Subject: [PATCH 5/5] crypt_make_salt(): try to use actual random bytes for salt generation In-Reply-To: References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> <20240415125628.780178-6-rasmus.villemoes@prevas.dk> <20240415190525.Zku33-4H@steffen%sdaoden.eu> Message-ID: <20240416180025.wDstSUsQ@steffen%sdaoden.eu> Rasmus Villemoes wrote in : |On 15/04/2024 21.05, Steffen Nurpmeso wrote: |> Rasmus Villemoes wrote in |> <20240415125628.780178-6-rasmus.villemoes at prevas.dk>: |>|Instead of limiting the possible generated salts to 2^32 different |>|ones, try to get some actual random bits and mix those in. Keep the |>|old pseudo-random generation in place, so that even if |>|open_read_close() fails or only returns a partial result, we're not |>|doing any worse than previously. |>| |>|In fact, even with /dev/urandom being unavailable, this might still |>|improve things a bit since whatever sort-of random content might be in |>|the p buffer on entry is then mixed in. |> |> By that time i thought (completely unrelated with your work) that |> the code from miscutils/seedrng.c which has a more broad view of |> where to get random data from should possibly be generalized. |> There are more than just one match for /dev/urandom, and they all |> want some random bits. | |Yeah, I know, I did go grepping for 'random' to see if bb already had |some "gimme some random bytes" helper, and I've also sort-of followed |the seedrng saga. But since there was no such helper, and just |best-effort here is good enough for a significant improvement in the |normal case, I just went with the oneliner open_read_close(), which is |also used in generate_uuid() without checking the return value. If some |common infrastructure for randomness should materialize, this can |trivially be switched over. But I really didn't want to tie this series |to creation of and bikeshedding over such infrastructure. Understandable. |Rasmus | --End of --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) From techtonik at gmail.com Tue Apr 16 18:13:15 2024 From: techtonik at gmail.com (anatoly techtonik) Date: Tue, 16 Apr 2024 21:13:15 +0300 Subject: Missing binaries / build system Message-ID: Hi, I want to use busybox_HTTPD as a minimal web server for serving static files in a container. busybox_HTTPD 2022-01-17 18:54 97K Unfortunately, the binaries https://busybox.net/downloads/binaries/ are only available for unstable 1.35.0 I tried to see what it takes to compile it (and make it really minimal) for the latest stable 1.36.1 release, but my knowledge of Makefile compilation toolchain is insufficient for the task. If there is a description of build automation that is used to make binary releases, maybe I can send some patches to fix it, -- anatoly t. From rep.dot.nop at gmail.com Tue Apr 16 19:02:21 2024 From: rep.dot.nop at gmail.com (rep.dot.nop at gmail.com) Date: Tue, 16 Apr 2024 21:02:21 +0200 Subject: Missing binaries / build system In-Reply-To: References: Message-ID: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> On 16 April 2024 20:13:15 CEST, anatoly techtonik wrote: >Hi, > >I want to use busybox_HTTPD as a minimal web server for serving >static files in a container. > > busybox_HTTPD 2022-01-17 18:54 97K > >Unfortunately, the binaries https://busybox.net/downloads/binaries/ >are only available for unstable 1.35.0 > >I tried to see what it takes to compile it (and make it really minimal) >for the latest stable 1.36.1 release, but my knowledge of Makefile >compilation toolchain is insufficient for the task. > >If there is a description of build automation that is used to make >binary releases, maybe I can send some patches to fix it, To build a busybox with just one applet make allnoconfig make menuconfig # select the applet(s) you need make ./busybox will then support the selected applets. HTH From misha.zavertkin at mail.ru Wed Apr 17 10:34:52 2024 From: misha.zavertkin at mail.ru (=?UTF-8?B?0JzQuNGI0LAg0JfQsNCy0ZHRgNGC0LrQuNC9?=) Date: Wed, 17 Apr 2024 13:34:52 +0300 Subject: =?UTF-8?B?W1BhdGNoXSBGaXggcGluZyBhY2NlcHRpbmcgb25seSBzYW1lIHNpemVkIHBh?= =?UTF-8?B?Y2tldHM=?= Message-ID: <1713350091.66360385@f457.i.mail.ru> Now ping expects response packets same size as sent. But 8.8.8.8 limit packet size. This makes ?ping -s 89 8.8.8.8??to fail ? The patch removes datalen from discarding short packages and makes calculating header length correct ? diff --git a/networking/ping.c b/networking/ping.c index b7e6955a9..ecf9c569e 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -696,7 +696,7 @@ static int unpack4(char *buf, int sz, struct sockaddr_in *from) ??? ?int hlen; ? ??? ?/* discard if too short */ -?? ?if (sz < (datalen + ICMP_MINLEN)) +?? ?if (sz < (sizeof(struct iphdr) + ICMP_MINLEN)) ??? ??? ?return 0; ? ??? ?/* check IP header */ @@ -732,7 +732,7 @@ static int unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit ??? ?char buf[INET6_ADDRSTRLEN]; ? ??? ?/* discard if too short */ -?? ?if (sz < (datalen + sizeof(struct icmp6_hdr))) +?? ?if (sz < sizeof(struct icmp6_hdr)) ??? ??? ?return 0; ? ??? ?icmppkt = (struct icmp6_hdr *) packet; ? ? ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From d.giritzer at danube-dynamics.at Wed Apr 17 11:25:28 2024 From: d.giritzer at danube-dynamics.at (Daniel Giritzer) Date: Wed, 17 Apr 2024 11:25:28 +0000 Subject: [PATCH] feat(syslogd): implement log rotation by log-age and by Message-ID: This patch allows syslogd to additionally rotate the log files by age and on a per-day basis. All settings can be configured either mutually exclusive or in combination. Mit freundlichen Gr??en | With kind regards Daniel Giritzer, MSc Certified Professional for Software Architecture T: +43 732 266277 E: d.giritzer at danube-dynamics.at L: Let?s connect on LinkedIn [Ein Bild, das Schrift, Grafiken, Text, Screenshot enth?lt. Automatisch generierte Beschreibung] Danube Dynamics Embedded Solutions GmbH Lastenstra?e 38/12. OG | 4020 Linz | Austria Registry Court: Linz Reg. No.: FN 536539 d VAT Reg. No.: ATU75804667 Web: www.danube-dynamics.at [Image] [Image] [Image] [Image] The information contained in this message may be confidential and legally protected under applicable law. The message is intended solely for the addressee(s). If you are not the intended recipient, you are hereby notified that any use, forwarding, dissemination, or reproduction of this message is strictly prohibited and may be unlawful. If you are not the intended recipient, please contact the sender by return e-mail and destroy all copies of the original message. See our privacy policy: https://www.danube-dynamics.at/datenschutz/ -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Outlook-Ein Bild, .png Type: image/png Size: 75397 bytes Desc: Outlook-Ein Bild, .png URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Outlook-Image.png Type: image/png Size: 990 bytes Desc: Outlook-Image.png URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Outlook-Image.png Type: image/png Size: 1090 bytes Desc: Outlook-Image.png URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Outlook-Image.png Type: image/png Size: 1393 bytes Desc: Outlook-Image.png URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Outlook-Image.png Type: image/png Size: 1072 bytes Desc: Outlook-Image.png URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-feat-syslogd-implement-log-rotation-by-log-age-and-b.patch Type: text/x-patch Size: 5857 bytes Desc: 0001-feat-syslogd-implement-log-rotation-by-log-age-and-b.patch URL: From techtonik at gmail.com Thu Apr 18 05:08:46 2024 From: techtonik at gmail.com (anatoly techtonik) Date: Thu, 18 Apr 2024 08:08:46 +0300 Subject: Missing binaries / build system In-Reply-To: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> Message-ID: On Tue, Apr 16, 2024 at 10:02?PM wrote: > > > To build a busybox with just one applet > make allnoconfig > make menuconfig > # select the applet(s) you need > make > > ./busybox will then support the selected applets. > > HTH Thanks. That helps. Got 84K busybox, then run make_single_applets.sh and got busybox_HTTPD 34K. Pretty awesome. =) Is there a way to select applets non-interactively for build automation? -- anatoly t. From yetanothergeek at gmail.com Thu Apr 18 08:05:09 2024 From: yetanothergeek at gmail.com (Jeff Pohlmeyer) Date: Thu, 18 Apr 2024 03:05:09 -0500 Subject: Missing binaries / build system In-Reply-To: References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> Message-ID: On Thu, Apr 18, 2024 at 12:09?AM anatoly techtonik wrote: > Is there a way to select applets non-interactively > for build automation? Maybe like this? ./make_single_applets.sh HTTPD ( You can use more than one UPPERCASE applet name to build several standalone applets at once ) -- Jeff From techtonik at gmail.com Fri Apr 19 09:29:24 2024 From: techtonik at gmail.com (anatoly techtonik) Date: Fri, 19 Apr 2024 12:29:24 +0300 Subject: Missing binaries / build system In-Reply-To: References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> Message-ID: On Thu, Apr 18, 2024 at 11:05?AM Jeff Pohlmeyer wrote: > > > Is there a way to select applets non-interactively > > for build automation? > > Maybe like this? > > ./make_single_applets.sh HTTPD It doesn't work without configuration. Says "No include/applets.h file". ./make defconfig ./make_single_applets.sh HTTPD This works, but produces 50K binary instead of 34K when selecting httpd in menuconfig interactively. -- anatoly t. From yetanothergeek at gmail.com Fri Apr 19 10:01:45 2024 From: yetanothergeek at gmail.com (Jeff Pohlmeyer) Date: Fri, 19 Apr 2024 05:01:45 -0500 Subject: Missing binaries / build system In-Reply-To: References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> Message-ID: On Fri, Apr 19, 2024 at 4:29?AM anatoly techtonik wrote: > ./make defconfig > ./make_single_applets.sh HTTPD > > This works, but produces 50K binary instead of 34K when selecting > httpd in menuconfig interactively. That is probably because "defconfig" enables a lot of features in the httpd applet that are disabled when you build with "allnoconfig" Things like: Date header, Last-Modified header, Range requests, HTTP authentication, custom error pages, reverse proxying, GZIP encoding, and CGI scripting. That's a lot of extra functionality for a 16K increase in size. You can of course go back in either config and enable/disable just the features you need, but I don't know how you would do that non-interactively. -- Jeff From git at sphalerite.org Fri Apr 19 10:21:44 2024 From: git at sphalerite.org (Linus Heckemann) Date: Fri, 19 Apr 2024 12:21:44 +0200 Subject: [PATCH] switch_root: remove /init check Message-ID: We were having some difficulty switching out of our custom initramfs into the final filesystem, with the error "message '/init' is not a regular file". We were confused as to why it was looking for `/init` -- we didn't have `/init`, neither in our initrd nor in the destination filesystem -- we were using the rdinit= command line parameter to provide an alternative path for the init in the initrd, and the target init was determined by userspace. Thankfully, the error message was fairly clear and easy to find in the source! We thus propose removing this check, since not all initrds have their init at /init -- setting rdinit= on the kernel command line allows using an alternative path. Thus, this check can prevent switching root in a scenario where it would be perfectly appropriate. --- util-linux/switch_root.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c index 14139736e..ef6669f5c 100644 --- a/util-linux/switch_root.c +++ b/util-linux/switch_root.c @@ -238,9 +238,6 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE // we mean it. I could make this a CONFIG option, but I would get email // from all the people who WILL destroy their filesystems. - if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) { - bb_error_msg_and_die("'%s' is not a regular file", "/init"); - } statfs("/", &stfs); // this never fails if ((unsigned)stfs.f_type != RAMFS_MAGIC && (unsigned)stfs.f_type != TMPFS_MAGIC -- 2.42.0 From explorer09 at gmail.com Fri Apr 19 11:25:26 2024 From: explorer09 at gmail.com (Kang-Che Sung) Date: Fri, 19 Apr 2024 19:25:26 +0800 Subject: [PATCH] switch_root: remove /init check In-Reply-To: References: Message-ID: Linus Heckemann ? 2024?4?19? ?????? > We were having some difficulty switching out of our custom initramfs > into the final filesystem, with the error "message '/init' is not a > regular file". We were confused as to why it was looking for `/init` > -- we didn't have `/init`, neither in our initrd nor in the > destination filesystem -- we were using the rdinit= command line > parameter to provide an alternative path for the init in the initrd, > and the target init was determined by userspace. > > Thankfully, the error message was fairly clear and easy to find in the > source! > > We thus propose removing this check, since not all initrds have their > init at /init -- setting rdinit= on the kernel command line allows > using an alternative path. Thus, this check can prevent switching root > in a scenario where it would be perfectly appropriate. > --- > util-linux/switch_root.c | 3 --- > 1 file changed, 3 deletions(-) > > diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c > index 14139736e..ef6669f5c 100644 > --- a/util-linux/switch_root.c > +++ b/util-linux/switch_root.c > @@ -238,9 +238,6 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) > // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE > // we mean it. I could make this a CONFIG option, but I would get email > // from all the people who WILL destroy their filesystems. > - if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) { > - bb_error_msg_and_die("'%s' is not a regular file", "/init"); > - } > statfs("/", &stfs); // this never fails > if ((unsigned)stfs.f_type != RAMFS_MAGIC > && (unsigned)stfs.f_type != TMPFS_MAGIC > -- > 2.42.0 Did you read the code comments on the lines above what you deleted? It's a sanity check before deleting everything on the "/" filesystem. Perhaps a better approach is to check the existence of what's specified in the "rdinit" parameter instead. -------------- next part -------------- An HTML attachment was scrubbed... URL: From farmatito at tiscali.it Fri Apr 19 11:36:02 2024 From: farmatito at tiscali.it (tito) Date: Fri, 19 Apr 2024 13:36:02 +0200 Subject: Missing binaries / build system In-Reply-To: References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> Message-ID: <20240419133602.5b1050cf@devuan> On Fri, 19 Apr 2024 05:01:45 -0500 Jeff Pohlmeyer wrote: > On Fri, Apr 19, 2024 at 4:29?AM anatoly techtonik wrote: > > > ./make defconfig > > ./make_single_applets.sh HTTPD > > > > This works, but produces 50K binary instead of 34K when selecting > > httpd in menuconfig interactively. > > That is probably because "defconfig" enables a lot of features in the > httpd applet that are disabled when you build with "allnoconfig" > > Things like: Date header, Last-Modified header, Range requests, HTTP > authentication, custom error pages, reverse proxying, GZIP encoding, > and CGI scripting. > > That's a lot of extra functionality for a 16K increase in size. You > can of course go back in either config and enable/disable just the > features you need, but I don't know how you would do that > non-interactively. Hi, you can just copy the .config file to the build directory. This will work as long as there are no new config options. Ciao, Tito > -- Jeff > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From techtonik at gmail.com Fri Apr 19 12:29:19 2024 From: techtonik at gmail.com (anatoly techtonik) Date: Fri, 19 Apr 2024 15:29:19 +0300 Subject: Missing binaries / build system In-Reply-To: References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> Message-ID: On Fri, Apr 19, 2024 at 1:02?PM Jeff Pohlmeyer wrote: > > That is probably because "defconfig" enables a lot of features in the > httpd applet that are disabled when you build with "allnoconfig" > > Things like: Date header, Last-Modified header, Range requests, HTTP > authentication, custom error pages, reverse proxying, GZIP encoding, > and CGI scripting. I've built it with allnoconfig+menuconfig, set "httpd" and all these features were seIected automatically, so they were present in 34K binary too. Looks like the binary size is affected by other default options. > That's a lot of extra functionality for a 16K increase in size. You > can of course go back in either config and enable/disable just the > features you need, but I don't know how you would do that > non-interactively. Yep, looks like there is no way to select configuration non-interactively. The "menu randconfig" is somehow able to click different options, so I guess it is just a matter of patching the build system to support "make enable httpd". Not sure if it is C, shell or make code that does the config management. -- anatoly t. From stuff at decentral.ch Fri Apr 19 16:48:57 2024 From: stuff at decentral.ch (Tim Tassonis) Date: Fri, 19 Apr 2024 18:48:57 +0200 Subject: Missing binaries / build system In-Reply-To: References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> Message-ID: <50229730-251a-415c-9802-9fd494294ab0@decentral.ch> On 4/19/24 14:29, anatoly techtonik wrote: > On Fri, Apr 19, 2024 at 1:02?PM Jeff Pohlmeyer wrote: >> >> That is probably because "defconfig" enables a lot of features in the >> httpd applet that are disabled when you build with "allnoconfig" >> >> Things like: Date header, Last-Modified header, Range requests, HTTP >> authentication, custom error pages, reverse proxying, GZIP encoding, >> and CGI scripting. > > I've built it with allnoconfig+menuconfig, set "httpd" and all these features > were seIected automatically, so they were present in 34K binary too. Looks > like the binary size is affected by other default options. > >> That's a lot of extra functionality for a 16K increase in size. You >> can of course go back in either config and enable/disable just the >> features you need, but I don't know how you would do that >> non-interactively. > > Yep, looks like there is no way to select configuration > non-interactively. The "menu randconfig" is somehow able to click > different options, so I guess it is just a matter of patching the build > system to support "make enable httpd". Not sure if it is C, shell or > make code that does the config management. Do you really think it is necessary to "fix" the build system in order to automatically support this special case? If you once have selected your desired stuff with everything unneeded, just keep your .config file and then re-use it. I don't want to stop you, but maybe everybody's precious time is better spent elsewhere than in automating esoteric special cases. Bye Tim From techtonik at gmail.com Fri Apr 19 22:51:33 2024 From: techtonik at gmail.com (anatoly techtonik) Date: Sat, 20 Apr 2024 01:51:33 +0300 Subject: Missing binaries / build system In-Reply-To: <50229730-251a-415c-9802-9fd494294ab0@decentral.ch> References: <64CC927C-4D69-4798-8D05-769CA144D2C2@gmail.com> <50229730-251a-415c-9802-9fd494294ab0@decentral.ch> Message-ID: On Fri, Apr 19, 2024 at 8:05?PM Tim Tassonis wrote: > > > Yep, looks like there is no way to select configuration > > non-interactively. The "menu randconfig" is somehow able to click > > different options, so I guess it is just a matter of patching the build > > system to support "make enable httpd". Not sure if it is C, shell or > > make code that does the config management. > > Do you really think it is necessary to "fix" the build system in order > to automatically support this special case? The build system is CI/CD that is supposed to upload the binaries automatically, but as I understandt, there is no such thing. Otherwise there would be no bugs like https://bugs.busybox.net/show_bug.cgi?id=14286 > If you once have selected your desired stuff with everything unneeded, > just keep your .config file and then re-use it. The config needs to be regenerated for each new release, and it is hard to memorize what was selected, but yes, it looks like that's just what everybody is doing. > I don't want to stop you, but maybe everybody's precious time is better > spent elsewhere than in automating esoteric special cases. With GitLab CI/CD there would be no problem automating binary releases. I don't think it is esoteric nowadays. -- anatoly t. From zhousiqi5 at huawei.com Mon Apr 22 01:58:40 2024 From: zhousiqi5 at huawei.com (zhousiqi (A)) Date: Mon, 22 Apr 2024 01:58:40 +0000 Subject: =?gb2312?B?tPC4tDogW1BhdGNoXSB1ZGhjcGM2OiBzdXBwb3J0IGdlbmVyYXRlIGEgY29u?= =?gb2312?Q?sistent_iaid?= In-Reply-To: References: Message-ID: <36f2498a1888402e9a6b764c00b6e77e@huawei.com> Gentle ping... Please check if the community accepts this submission. > -----????----- > ???: zhousiqi (A) > ????: 2024?4?12? 15:09 > ???: busybox at busybox.net > ??: [Patch] udhcpc6: support generate a consistent iaid > > Currently, udhcpc6 does not meet the requirements for Identity Association in > RFC 3315. > This is a specific explanation of RFC 3315 protocol: > https://datatracker.ietf.org/doc/html/rfc3315#section-10 > ?The IAID uniquely identifies the IA and must be chosen to be unique > among the IAIDs on the client. The IAID is chosen by the client. > For any given use of an IA by the client, the IAID for that IA MUST > be consistent across restarts of the DHCP client.? > This patch allows the client to generate a consistent IAID based on the MAC > address. > > Signed-off-by: Zhou Siqi > --- > networking/udhcp/d6_dhcpc.c | 30 ++++++++++++++++++++++++++++-- > 1 file changed, 28 insertions(+), 2 deletions(-) > > diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c > index a35488d..99a53c8 100644 > --- a/networking/udhcp/d6_dhcpc.c > +++ b/networking/udhcp/d6_dhcpc.c > @@ -741,6 +741,32 @@ static NOINLINE int send_d6_info_request(void) > | OPTION_RECONF_ACCEPT | 0 > | > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > */ > + > +/*obtain a consistent IAID based on the MAC address*/ static int > +d6_create_iaid() { > + int data = 0; > + int start_idx = 0, copy_len = 0; > + int mac_len = 0; > + > + mac_len = sizeof(client_data.client_mac); > + > + /* > + * A simple IAID is the last 4 bytes > + * of the hardware address. > + */ > + if (mac_len > 4) { > + start_idx = mac_len - 4; > + copy_len = 4; > + } else { > + copy_len = mac_len; > + } > + > + memcpy(&data, &client_data.client_mac[start_idx], copy_len); > + > + return data; > +} > + > /* NOINLINE: limit stack usage in caller */ static NOINLINE int > send_d6_discover(struct in6_addr *requested_ipv6) { @@ -759,7 +785,7 @@ > static NOINLINE int send_d6_discover(struct in6_addr *requested_ipv6) > client6_data.ia_na = xzalloc(len); > client6_data.ia_na->code = D6_OPT_IA_NA; > client6_data.ia_na->len = len - 4; > - *(bb__aliased_uint32_t*)client6_data.ia_na->data = rand(); > /* IAID */ > + *(bb__aliased_uint32_t*)client6_data.ia_na->data = > + d6_create_iaid(); /* IAID */ > if (requested_ipv6) { > struct d6_option *iaaddr = > (void*)(client6_data.ia_na->data + 4+4+4); > iaaddr->code = D6_OPT_IAADDR; @@ -777,7 > +803,7 @@ static NOINLINE int send_d6_discover(struct in6_addr > *requested_ipv6) > client6_data.ia_pd = xzalloc(len); > client6_data.ia_pd->code = D6_OPT_IA_PD; > client6_data.ia_pd->len = len - 4; > - *(bb__aliased_uint32_t*)client6_data.ia_pd->data = rand(); > /* IAID */ > + *(bb__aliased_uint32_t*)client6_data.ia_pd->data = > + d6_create_iaid(); /* IAID */ > opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, len); > } From philipp_subx at redfish-solutions.com Mon Apr 22 16:16:03 2024 From: philipp_subx at redfish-solutions.com (Philip Prindeville) Date: Mon, 22 Apr 2024 10:16:03 -0600 Subject: Off-topic: filtering stream of pathnames for glob'd exclusions Message-ID: <7D1D0415-CD86-43D5-9AF5-CDDDC96AA9AC@redfish-solutions.com> Hi, Somewhat off-topic post but this is on a system that has Busybox installed so I can't use features that other shells might provide. I have a stream generated by "find" of pathnames, and I want to delete (filter out) certain paths based on the contents of a file that holds exclusions. Anyone know an easy way to do this? Something like "... | grep -v -f exclusions.txt" if grep worked with globs instead of patterns... Any suggestions? Thanks, -Philip From David.Laight at ACULAB.COM Mon Apr 22 16:41:56 2024 From: David.Laight at ACULAB.COM (David Laight) Date: Mon, 22 Apr 2024 16:41:56 +0000 Subject: Off-topic: filtering stream of pathnames for glob'd exclusions In-Reply-To: <7D1D0415-CD86-43D5-9AF5-CDDDC96AA9AC@redfish-solutions.com> References: <7D1D0415-CD86-43D5-9AF5-CDDDC96AA9AC@redfish-solutions.com> Message-ID: <9e0b09c42cad47c487391c710a6a122f@AcuMS.aculab.com> From: Philip Prindeville > Sent: 22 April 2024 17:16 > Somewhat off-topic post but this is on a system that has Busybox installed so I can't use features > that other shells might provide. > > I have a stream generated by "find" of pathnames, and I want to delete (filter out) certain paths > based on the contents of a file that holds exclusions. > > Anyone know an easy way to do this? Something like "... | grep -v -f exclusions.txt" if grep worked > with globs instead of patterns... A shell 'case' statement will do filename 'glob' matching. so something like: find ... | while read path; do case $path in (exclusion_1 | exclusion_2 ...) ;; (*) echo $path;; esac done might work (modulo some extra quoting - probably ' around the patterns). That does require a pre-process of your exclusions.txt file. With a bit of care you can use the shells eval on the entire case statement to do that in the script itself. If you use eval make sure you quote everything except the variables you want expanded on the first pass. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) From schoen at loyalty.org Mon Apr 22 20:48:02 2024 From: schoen at loyalty.org (Seth David Schoen) Date: Mon, 22 Apr 2024 13:48:02 -0700 Subject: Off-topic: filtering stream of pathnames for glob'd exclusions In-Reply-To: <7D1D0415-CD86-43D5-9AF5-CDDDC96AA9AC@redfish-solutions.com> References: <7D1D0415-CD86-43D5-9AF5-CDDDC96AA9AC@redfish-solutions.com> Message-ID: Philip Prindeville writes: > Hi, > > Somewhat off-topic post but this is on a system that has Busybox installed so I can't use features that other shells might provide. > > I have a stream generated by "find" of pathnames, and I want to delete (filter out) certain paths based on the contents of a file that holds exclusions. If you can modify the find command itself, you could add a "-not -path" clause with a glob pattern. For example, find / -not -path '*e*' finds all paths on the system that don't contain the letter e. If there aren't too many such lines, you could make a "-not -path" clause for each of them. From git at sphalerite.org Tue Apr 23 09:13:20 2024 From: git at sphalerite.org (Linus Heckemann) Date: Tue, 23 Apr 2024 11:13:20 +0200 Subject: [PATCH] switch_root: remove /init check In-Reply-To: References: Message-ID: Kang-Che Sung writes: > Linus Heckemann ? 2024?4?19? ?????? >> We were having some difficulty switching out of our custom initramfs >> into the final filesystem, with the error "message '/init' is not a >> regular file". We were confused as to why it was looking for `/init` >> -- we didn't have `/init`, neither in our initrd nor in the >> destination filesystem -- we were using the rdinit= command line >> parameter to provide an alternative path for the init in the initrd, >> and the target init was determined by userspace. >> >> Thankfully, the error message was fairly clear and easy to find in the >> source! >> >> We thus propose removing this check, since not all initrds have their >> init at /init -- setting rdinit= on the kernel command line allows >> using an alternative path. Thus, this check can prevent switching root >> in a scenario where it would be perfectly appropriate. >> --- >> util-linux/switch_root.c | 3 --- >> 1 file changed, 3 deletions(-) >> >> diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c >> index 14139736e..ef6669f5c 100644 >> --- a/util-linux/switch_root.c >> +++ b/util-linux/switch_root.c >> @@ -238,9 +238,6 @@ int switch_root_main(int argc UNUSED_PARAM, char > **argv) >> // Additional sanity checks: we're about to rm -rf /, so be > REALLY SURE >> // we mean it. I could make this a CONFIG option, but I would get > email >> // from all the people who WILL destroy their filesystems. >> - if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) { >> - bb_error_msg_and_die("'%s' is not a regular file", > "/init"); >> - } >> statfs("/", &stfs); // this never fails >> if ((unsigned)stfs.f_type != RAMFS_MAGIC >> && (unsigned)stfs.f_type != TMPFS_MAGIC >> -- >> 2.42.0 > > Did you read the code comments on the lines above what you deleted? It's a > sanity check before deleting everything on the "/" filesystem. I did! I don't really see the existence of /init being so critical for this check given that we check below that it's a ramfs or tmpfs, which seems to me to be enough that people won't be destroying filesystems they cared a great deal about. > Perhaps a better approach is to check the existence of what's specified in > the "rdinit" parameter instead. That would introduce an additional dependency on /proc being mounted and require additional parsing. I don't think the check is that necessary, again because we have the /-is-ramfs-or-tmpfs check. But if you do think we need it I can rewrite the patch to check for rdinit= on cmdline as well. Cheers Linus From explorer09 at gmail.com Tue Apr 23 10:07:21 2024 From: explorer09 at gmail.com (Kang-Che Sung) Date: Tue, 23 Apr 2024 18:07:21 +0800 Subject: [PATCH] switch_root: remove /init check In-Reply-To: References: Message-ID: Linus Heckemann ? 2024?4?23? ?????? > > I don't really see the existence of /init being so critical for > this check given that we check below that it's a ramfs or tmpfs, which > seems to me to be enough that people won't be destroying filesystems > they cared a great deal about. > The ramfs/tmpfs check was good as it won't destroy any _permanent_ file the user could have, but it wouldn't hurt either when there is another sanity check. >> Perhaps a better approach is to check the existence of what's specified in >> the "rdinit" parameter instead. > > That would introduce an additional dependency on /proc being mounted and > require additional parsing. I don't think the check is that necessary, > again because we have the /-is-ramfs-or-tmpfs check. But if you do think > we need it I can rewrite the patch to check for rdinit= on cmdline as well. > /proc should be mounted by most init systems anyway. But we can skip the check when /proc doesn't exist, just in case. The logic would be roughly like this: If "/proc/cmdline" exists Read the "rdinit" parameter from "/proc/cmdline"; if it's unspecified, default to "/init" If the file in "rdinit" doesn't exist, stop. Else Skip the "rdinit" existence check and continue the switch_root process -------------- next part -------------- An HTML attachment was scrubbed... URL: From sam at gentoo.org Tue Apr 23 20:10:18 2024 From: sam at gentoo.org (Sam James) Date: Tue, 23 Apr 2024 21:10:18 +0100 Subject: [PATCH v2] fixdep: add fstat error handling Message-ID: <20240423201029.2644201-1-sam@gentoo.org> When `fstat` fails, `st` is left uninitialised. In our case, Ben Kohler noticed our release media builds were failing in Gentoo on x86 when building busybox with occasional SIGBUS. This turned out to be EOVERFLOW (from 32-bit ino_t) which wasn't being reported because nothing was checking the return value from `fstat`. Fix that to avoid UB (use of uninit var) and to give a more friendly error to the user. This actually turns out to be fixed already in the kernel from back in 2010 [0] and 2016 [1]. [0] https://github.com/torvalds/linux/commit/a3ba81131aca243bfecfa78c42edec0cd69f72d6 [1] https://github.com/torvalds/linux/commit/46fe94ad18aa7ce6b3dad8c035fb538942020f2b Reported-by: Ben Kohler Signed-off-by: Sam James --- scripts/basic/fixdep.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 66be73aad..ebc715730 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -292,7 +292,11 @@ void do_config_file(char *filename) perror(filename); exit(2); } - fstat(fd, &st); + if (fstat(fd, &st) < 0) { + fprintf(stderr, "fixdep: fstat"); + perror(filename); + exit(2); + } if (st.st_size == 0) { close(fd); return; @@ -368,7 +372,11 @@ void print_deps(void) perror(depfile); exit(2); } - fstat(fd, &st); + if (fstat(fd, &st) < 0) { + fprintf(stderr, "fixdep: fstat"); + perror(depfile); + exit(2); + } if (st.st_size == 0) { fprintf(stderr,"fixdep: %s is empty\n",depfile); close(fd); -- 2.44.0 From wouter.franken_ext at softathome.com Wed Apr 24 08:49:22 2024 From: wouter.franken_ext at softathome.com (Wouter Franken) Date: Wed, 24 Apr 2024 10:49:22 +0200 Subject: [PATCH] libbb/loop: fix existence check for LOOP_CONFIGURE ioctl Message-ID: <20240424084922.155782-1-wouter.franken_ext@softathome.com> The LOOP_CONFIGURE ioctl is supported in 5.8 kernels and up. To have backwards compatibility there is a config option CONFIG_TRY_LOOP_CONFIGURE that will check if the ioctl exists and if not fall back to old way of configuring loop devices. Normally errno will be set to EINVAL when this ioctl does not exist. However, when kernel config CONFIG_COMPAT is enabled, then compat_ioctl is called. In that case -ENOIOCTLCMD is returned by loop device driver and generic ioctl wrapper will set errno to ENOTTY. Because busybox does not expect this it will fail to mount loop devices in this case. This patch fixes the check for the existence of the ioctl LOOP_CONFIGURE by checking if errno is one of both: EINVAL or ENOTTY. Signed-off-by: Wouter Franken Signed-off-by: Wouter Franken --- libbb/loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbb/loop.c b/libbb/loop.c index a0c5d0259..b603d0daa 100644 --- a/libbb/loop.c +++ b/libbb/loop.c @@ -158,7 +158,7 @@ static int set_loopdev_params(int lfd, if (rc == 0) return rc; /* SUCCESS! */ # if ENABLE_TRY_LOOP_CONFIGURE - if (errno != EINVAL) + if (errno != EINVAL && errno != ENOTTY) return rc; /* error other than old kernel */ /* Old kernel, fall through into old way to do it: */ # endif -- 2.34.1 -- This message and any attachments herein are confidential, intended solely for the addressees and are SoftAtHome?s ownership. Any unauthorized use or dissemination is prohibited. If you are not the intended addressee of this message, please cancel it immediately and inform the sender. From adam at westernsemico.com Thu Apr 25 04:22:28 2024 From: adam at westernsemico.com (Adam Joseph) Date: Wed, 24 Apr 2024 21:22:28 -0700 Subject: [PATCH] modprobe: implement -d DIR flag like the modprobe in kmod Message-ID: <20240425042227.24793-2-adam@westernsemico.com> This patch implements support for the `-d DIR` flag, like kmod has. When provided, `DIR` is a directory *beneath which* modprobe will expect to find $CONFIG_DEFAULT_MODULES_DIR/$(uname -r) (e.g. lib/modules/$(uname -r)). This is required on nixpkgs-based systems, which do not normally have a /lib/modules directory. Instead, a symbolic link at some ephemeral location in /run points to the proper location. For example, with mdevd instead of systemd and the following in mdev.conf: mdevd-conf = '' ... $MODALIAS=.* root:root 660 @${pkgs.busybox}/bin/modprobe -d /run/booted-system/kernel-modules -b "$MODALIAS" ... ''; Compared to setting CONFIG_DEFAULT_MODULES_DIR, a command line flag is preferable since it allows the same busybox binary to be used both in early userspace (where the initrd layout often follows FHS and uses /lib/modules) as well as after switch_root. --- modutils/modprobe.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 543f53e99..d3690ebc1 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -114,6 +114,7 @@ //usage: " MODULE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") //usage:#define modprobe_full_usage "\n\n" //usage: " -a Load multiple MODULEs" +//usage: "\n -d DIR Use DIR as filesystem root" //usage: "\n -l List (MODULE is a pattern)" //usage: "\n -r Remove MODULE (stacks) or do autoclean" //usage: "\n -q Quiet" @@ -130,7 +131,7 @@ * Note2: -b is always accepted, but if !FEATURE_MODPROBE_BLACKLIST, * it is a no-op. */ -#define MODPROBE_OPTS "alrDb" +#define MODPROBE_OPTS "ad:lrDb" /* -a and -D _are_ in fact compatible */ #define MODPROBE_COMPLEMENTARY "q-v:v-q:l--arD:r--alD:a--lr:D--rl" //#define MODPROBE_OPTS "acd:lnrt:C:b" @@ -138,20 +139,21 @@ enum { OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */ //OPT_DUMP_ONLY = (INSMOD_OPT_UNUSED << x), /* c */ - //OPT_DIRNAME = (INSMOD_OPT_UNUSED << x), /* d */ - OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 1), /* l */ + OPT_DIRNAME = (INSMOD_OPT_UNUSED << 1), /* d */ + OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 2), /* l */ //OPT_SHOW_ONLY = (INSMOD_OPT_UNUSED << x), /* n */ - OPT_REMOVE = (INSMOD_OPT_UNUSED << 2), /* r */ + OPT_REMOVE = (INSMOD_OPT_UNUSED << 3), /* r */ //OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */ //OPT_VERONLY = (INSMOD_OPT_UNUSED << x), /* V */ //OPT_CONFIGFILE = (INSMOD_OPT_UNUSED << x), /* C */ - OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 3), /* D */ - OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 4) * ENABLE_FEATURE_MODPROBE_BLACKLIST, + OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 4), /* D */ + OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 5) * ENABLE_FEATURE_MODPROBE_BLACKLIST, }; #if ENABLE_LONG_OPTS static const char modprobe_longopts[] ALIGN1 = /* nobody asked for long opts (yet) */ // "all\0" No_argument "a" + // "dirname\0" required_argument "d" // "list\0" No_argument "l" // "remove\0" No_argument "r" // "quiet\0" No_argument "q" @@ -559,17 +561,25 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) int rc; unsigned opt; struct module_entry *me; + const char* dirname; INIT_G(); opt = getopt32long(argv, "^" INSMOD_OPTS MODPROBE_OPTS "\0" MODPROBE_COMPLEMENTARY, modprobe_longopts INSMOD_ARGS + , &dirname ); argv += optind; /* Goto modules location */ - xchdir(CONFIG_DEFAULT_MODULES_DIR); + if (opt & OPT_DIRNAME) { + xchdir(dirname); + xchdir(&CONFIG_DEFAULT_MODULES_DIR[1]); + } else { + xchdir(CONFIG_DEFAULT_MODULES_DIR); + } + uname(&G.uts); xchdir(G.uts.release); -- 2.44.0 From farmatito at tiscali.it Thu Apr 25 07:13:09 2024 From: farmatito at tiscali.it (tito) Date: Thu, 25 Apr 2024 09:13:09 +0200 Subject: [PATCH] modprobe: implement -d DIR flag like the modprobe in kmod In-Reply-To: <20240425042227.24793-2-adam@westernsemico.com> References: <20240425042227.24793-2-adam@westernsemico.com> Message-ID: <20240425091309.49ed3491@devuan> On Wed, 24 Apr 2024 21:22:28 -0700 Adam Joseph wrote: > This patch implements support for the `-d DIR` flag, like kmod has. When > provided, `DIR` is a directory *beneath which* modprobe will expect to find > $CONFIG_DEFAULT_MODULES_DIR/$(uname -r) (e.g. lib/modules/$(uname -r)). > > This is required on nixpkgs-based systems, which do not normally have a > /lib/modules directory. Instead, a symbolic link at some ephemeral location > in /run points to the proper location. For example, with mdevd instead of > systemd and the following in mdev.conf: > > mdevd-conf = '' > ... > $MODALIAS=.* root:root 660 @${pkgs.busybox}/bin/modprobe -d /run/booted-system/kernel-modules -b "$MODALIAS" > ... > ''; > > Compared to setting CONFIG_DEFAULT_MODULES_DIR, a command line flag is > preferable since it allows the same busybox binary to be used both in early > userspace (where the initrd layout often follows FHS and uses /lib/modules) as > well as after switch_root. > --- > modutils/modprobe.c | 24 +++++++++++++++++------- > 1 file changed, 17 insertions(+), 7 deletions(-) > > diff --git a/modutils/modprobe.c b/modutils/modprobe.c > index 543f53e99..d3690ebc1 100644 > --- a/modutils/modprobe.c > +++ b/modutils/modprobe.c > @@ -114,6 +114,7 @@ > //usage: " MODULE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") > //usage:#define modprobe_full_usage "\n\n" > //usage: " -a Load multiple MODULEs" > +//usage: "\n -d DIR Use DIR as filesystem root" > //usage: "\n -l List (MODULE is a pattern)" > //usage: "\n -r Remove MODULE (stacks) or do autoclean" > //usage: "\n -q Quiet" > @@ -130,7 +131,7 @@ > * Note2: -b is always accepted, but if !FEATURE_MODPROBE_BLACKLIST, > * it is a no-op. > */ > -#define MODPROBE_OPTS "alrDb" > +#define MODPROBE_OPTS "ad:lrDb" > /* -a and -D _are_ in fact compatible */ > #define MODPROBE_COMPLEMENTARY "q-v:v-q:l--arD:r--alD:a--lr:D--rl" > //#define MODPROBE_OPTS "acd:lnrt:C:b" > @@ -138,20 +139,21 @@ > enum { > OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */ > //OPT_DUMP_ONLY = (INSMOD_OPT_UNUSED << x), /* c */ > - //OPT_DIRNAME = (INSMOD_OPT_UNUSED << x), /* d */ > - OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 1), /* l */ > + OPT_DIRNAME = (INSMOD_OPT_UNUSED << 1), /* d */ > + OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 2), /* l */ > //OPT_SHOW_ONLY = (INSMOD_OPT_UNUSED << x), /* n */ > - OPT_REMOVE = (INSMOD_OPT_UNUSED << 2), /* r */ > + OPT_REMOVE = (INSMOD_OPT_UNUSED << 3), /* r */ > //OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */ > //OPT_VERONLY = (INSMOD_OPT_UNUSED << x), /* V */ > //OPT_CONFIGFILE = (INSMOD_OPT_UNUSED << x), /* C */ > - OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 3), /* D */ > - OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 4) * ENABLE_FEATURE_MODPROBE_BLACKLIST, > + OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 4), /* D */ > + OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 5) * ENABLE_FEATURE_MODPROBE_BLACKLIST, > }; > #if ENABLE_LONG_OPTS > static const char modprobe_longopts[] ALIGN1 = > /* nobody asked for long opts (yet) */ > // "all\0" No_argument "a" > + // "dirname\0" required_argument "d" > // "list\0" No_argument "l" > // "remove\0" No_argument "r" > // "quiet\0" No_argument "q" > @@ -559,17 +561,25 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) > int rc; > unsigned opt; > struct module_entry *me; > + const char* dirname; > > INIT_G(); > > opt = getopt32long(argv, "^" INSMOD_OPTS MODPROBE_OPTS "\0" MODPROBE_COMPLEMENTARY, > modprobe_longopts > INSMOD_ARGS > + , &dirname > ); > argv += optind; > > /* Goto modules location */ > - xchdir(CONFIG_DEFAULT_MODULES_DIR); > + if (opt & OPT_DIRNAME) { Hi, just out of curiosity what are you trying to achieve here? To which directory you want to change? dirname or &CONFIG_DEFAULT_MODULES_DIR[1]? and why not xchdir(CONFIG_DEFAULT_MODULES_DIR) like later on in the code? Also I would like to point out that if the first xchdir call fails the program will exit and the second will never be executed. Ciao, Tito > + xchdir(dirname); > + xchdir(&CONFIG_DEFAULT_MODULES_DIR[1]); > + } else { > + xchdir(CONFIG_DEFAULT_MODULES_DIR); > + } > + > uname(&G.uts); > xchdir(G.uts.release); > From farmatito at tiscali.it Thu Apr 25 07:33:09 2024 From: farmatito at tiscali.it (tito) Date: Thu, 25 Apr 2024 09:33:09 +0200 Subject: [PATCH] modprobe: implement -d DIR flag like the modprobe in kmod In-Reply-To: <20240425091309.49ed3491@devuan> References: <20240425042227.24793-2-adam@westernsemico.com> <20240425091309.49ed3491@devuan> Message-ID: <20240425093309.424f74dd@devuan> On Thu, 25 Apr 2024 09:13:09 +0200 tito wrote: > On Wed, 24 Apr 2024 21:22:28 -0700 > Adam Joseph wrote: > > > This patch implements support for the `-d DIR` flag, like kmod has. When > > provided, `DIR` is a directory *beneath which* modprobe will expect to find > > $CONFIG_DEFAULT_MODULES_DIR/$(uname -r) (e.g. lib/modules/$(uname -r)). > > > > This is required on nixpkgs-based systems, which do not normally have a > > /lib/modules directory. Instead, a symbolic link at some ephemeral location > > in /run points to the proper location. For example, with mdevd instead of > > systemd and the following in mdev.conf: > > > > mdevd-conf = '' > > ... > > $MODALIAS=.* root:root 660 @${pkgs.busybox}/bin/modprobe -d /run/booted-system/kernel-modules -b "$MODALIAS" > > ... > > ''; > > > > Compared to setting CONFIG_DEFAULT_MODULES_DIR, a command line flag is > > preferable since it allows the same busybox binary to be used both in early > > userspace (where the initrd layout often follows FHS and uses /lib/modules) as > > well as after switch_root. > > --- > > modutils/modprobe.c | 24 +++++++++++++++++------- > > 1 file changed, 17 insertions(+), 7 deletions(-) > > > > diff --git a/modutils/modprobe.c b/modutils/modprobe.c > > index 543f53e99..d3690ebc1 100644 > > --- a/modutils/modprobe.c > > +++ b/modutils/modprobe.c > > @@ -114,6 +114,7 @@ > > //usage: " MODULE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") > > //usage:#define modprobe_full_usage "\n\n" > > //usage: " -a Load multiple MODULEs" > > +//usage: "\n -d DIR Use DIR as filesystem root" > > //usage: "\n -l List (MODULE is a pattern)" > > //usage: "\n -r Remove MODULE (stacks) or do autoclean" > > //usage: "\n -q Quiet" > > @@ -130,7 +131,7 @@ > > * Note2: -b is always accepted, but if !FEATURE_MODPROBE_BLACKLIST, > > * it is a no-op. > > */ > > -#define MODPROBE_OPTS "alrDb" > > +#define MODPROBE_OPTS "ad:lrDb" > > /* -a and -D _are_ in fact compatible */ > > #define MODPROBE_COMPLEMENTARY "q-v:v-q:l--arD:r--alD:a--lr:D--rl" > > //#define MODPROBE_OPTS "acd:lnrt:C:b" > > @@ -138,20 +139,21 @@ > > enum { > > OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */ > > //OPT_DUMP_ONLY = (INSMOD_OPT_UNUSED << x), /* c */ > > - //OPT_DIRNAME = (INSMOD_OPT_UNUSED << x), /* d */ > > - OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 1), /* l */ > > + OPT_DIRNAME = (INSMOD_OPT_UNUSED << 1), /* d */ > > + OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 2), /* l */ > > //OPT_SHOW_ONLY = (INSMOD_OPT_UNUSED << x), /* n */ > > - OPT_REMOVE = (INSMOD_OPT_UNUSED << 2), /* r */ > > + OPT_REMOVE = (INSMOD_OPT_UNUSED << 3), /* r */ > > //OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */ > > //OPT_VERONLY = (INSMOD_OPT_UNUSED << x), /* V */ > > //OPT_CONFIGFILE = (INSMOD_OPT_UNUSED << x), /* C */ > > - OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 3), /* D */ > > - OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 4) * ENABLE_FEATURE_MODPROBE_BLACKLIST, > > + OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 4), /* D */ > > + OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 5) * ENABLE_FEATURE_MODPROBE_BLACKLIST, > > }; > > #if ENABLE_LONG_OPTS > > static const char modprobe_longopts[] ALIGN1 = > > /* nobody asked for long opts (yet) */ > > // "all\0" No_argument "a" > > + // "dirname\0" required_argument "d" > > // "list\0" No_argument "l" > > // "remove\0" No_argument "r" > > // "quiet\0" No_argument "q" > > @@ -559,17 +561,25 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) > > int rc; > > unsigned opt; > > struct module_entry *me; > > + const char* dirname; > > > > INIT_G(); > > > > opt = getopt32long(argv, "^" INSMOD_OPTS MODPROBE_OPTS "\0" MODPROBE_COMPLEMENTARY, > > modprobe_longopts > > INSMOD_ARGS > > + , &dirname > > ); > > argv += optind; > > > > /* Goto modules location */ > > - xchdir(CONFIG_DEFAULT_MODULES_DIR); > > + if (opt & OPT_DIRNAME) { > Hi, > just out of curiosity what are you trying to achieve here? > To which directory you want to change? dirname or &CONFIG_DEFAULT_MODULES_DIR[1]? > and why not xchdir(CONFIG_DEFAULT_MODULES_DIR) like later on in the code? > Also I would like to point out that if the first xchdir call fails the program will exit > and the second will never be executed. > > Ciao, > Tito Hi again, I see now what this is about something like: if (opt & OPT_DIRNAME) { xchdir(dirname); /* remove first / */ CONFIG_DEFAULT_MODULES_DIR+=1; } xchdir(CONFIG_DEFAULT_MODULES_DIR); This spares a xchdir call and from my point of view makes it easier to understand. Sorry for the noise. Ciao, Tito > > > + xchdir(dirname); > > + xchdir(&CONFIG_DEFAULT_MODULES_DIR[1]); > > > > + } else { > > + xchdir(CONFIG_DEFAULT_MODULES_DIR); > > + } > > + > > uname(&G.uts); > > xchdir(G.uts.release); > > > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From d+busybox at adaptive-enterprises.com Thu Apr 25 08:21:01 2024 From: d+busybox at adaptive-enterprises.com (David Leonard) Date: Thu, 25 Apr 2024 18:21:01 +1000 (AEST) Subject: [PATCH v2] fixdep: add fstat error handling In-Reply-To: <20240423201029.2644201-1-sam@gentoo.org> References: <20240423201029.2644201-1-sam@gentoo.org> Message-ID: <60o10n01-70q9-p3oo-o70r-np2n6o58s21s@nqncgvir-ragrecevfrf.pbz> On Tue, 23 Apr 2024, Sam James wrote: > } > - fstat(fd, &st); > + if (fstat(fd, &st) < 0) { > + fprintf(stderr, "fixdep: fstat"); > + perror(filename); > + exit(2); > + } > if (st.st_size == 0) { > close(fd); > return; > @@ -368,7 +372,11 @@ void print_deps(void) > perror(depfile); > exit(2); > } > - fstat(fd, &st); > + if (fstat(fd, &st) < 0) { > + fprintf(stderr, "fixdep: fstat"); > + perror(depfile); > + exit(2); > + } > if (st.st_size == 0) { > fprintf(stderr,"fixdep: %s is empty\n",depfile); > close(fd); I worry that the fprintf() may destroy the errno which perror() uses, so you could get a random error message. Perhaps remove the fprintf(s) completely? Because the context should be clear enough from the filename alone that perror displays. David From rasmus.villemoes at prevas.dk Mon Apr 29 06:57:03 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 29 Apr 2024 08:57:03 +0200 Subject: [PATCH 0/5] simplify and improve crypt_make_salt() In-Reply-To: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> References: <20240415125628.780178-1-rasmus.villemoes@prevas.dk> Message-ID: <7a3028b5-ccc0-428d-96c9-c98cdec61b69@prevas.dk> On 15/04/2024 14.56, Rasmus Villemoes wrote: > Currently, crypt_make_salt() can only return 2^28 different salt > strings. There are some low-hanging fruits allowing us to reduce the > code size, and even with patch 5 which obviously by itself increases > the footprint, the combined result of these patches is > > function old new delta > crypt_make_salt 104 95 -9 > i64c 41 24 -17 > ------------------------------------------------------------------------------ > (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-26) Total: -26 bytes > > while making sure (in the normal case where /dev/urandom is available) > that the salt string is completely random, and that we are not in any > case doing worse than what the current code does. If there are no other comments, could these be considered for applying? Thanks, Rasmus > > Rasmus Villemoes (5): > pw_encrypt.c: make i64c() slightly smaller > crypt_make_salt: cleanup leftover comments > crypt_make_salt(): simplify and improve > crypt_make_salt(): fixup odd calling convention > crypt_make_salt(): try to use actual random bytes for salt generation > > include/libbb.h | 11 ++--------- > libbb/pw_encrypt.c | 27 +++++++++++---------------- > networking/httpd.c | 2 +- > 3 files changed, 14 insertions(+), 26 deletions(-) > From peter.kaestle at nokia.com Mon Apr 29 11:14:09 2024 From: peter.kaestle at nokia.com (Peter Kaestle) Date: Mon, 29 Apr 2024 13:14:09 +0200 Subject: [PATCH 0/1] CVE-2023-39810 fix proposal Message-ID: <20240429111410.1430555-1-peter.kaestle@nokia.com> Hello busybox community, as I haven't seen much ongoin about the path traversal problem of CVE-2023-39810, I spent some time on it and want to share a poposal how it could be mitigated. Happy to see some comments on my proposal. Thank you very much and best regards --peter; Peter Kaestle (1): archival: new option to disallow path traversals archival/Config.src | 7 +++++++ archival/libarchive/data_extract_all.c | 22 ++++++++++++++++++++++ testsuite/cpio.tests | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+) -- 2.44.0 From peter.kaestle at nokia.com Mon Apr 29 11:14:10 2024 From: peter.kaestle at nokia.com (Peter Kaestle) Date: Mon, 29 Apr 2024 13:14:10 +0200 Subject: [PATCH 1/1] archival: new option to disallow path traversals In-Reply-To: <20240429111410.1430555-1-peter.kaestle@nokia.com> References: <20240429111410.1430555-1-peter.kaestle@nokia.com> Message-ID: <20240429111410.1430555-2-peter.kaestle@nokia.com> Create new configure option for archival/libarchive based extractions to disallow path traversals. As this is a paranoid option and might introduce backward incompatibiltiy, default it to no. Fixes: CVE-2023-39810 Signed-off-by: Peter Kaestle Reviewed-by: Samuel Sapalski --- archival/Config.src | 7 +++++++ archival/libarchive/data_extract_all.c | 22 ++++++++++++++++++++++ testsuite/cpio.tests | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/archival/Config.src b/archival/Config.src index 6f4f30c43..ac9d3db95 100644 --- a/archival/Config.src +++ b/archival/Config.src @@ -35,4 +35,11 @@ config FEATURE_LZMA_FAST This option reduces decompression time by about 25% at the cost of a 1K bigger binary. +config FEATURE_PATH_TRAVERSAL_PROTECTION + bool "enable path traversal protection" + default n + help + This option will disallow extraction of files outside of the + destination directory. + endmenu diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 049c2c156..cb5d5c4ca 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c @@ -66,6 +66,28 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) } #endif +#if ENABLE_FEATURE_PATH_TRAVERSAL_PROTECTION + if (strstr(dst_name, "../")) { + char *resolved_dst_path, *cwd; + + cwd = getcwd(NULL, 0); + + resolved_dst_path = xmalloc_realpath_coreutils(dst_name); + if (resolved_dst_path) { + if (strncmp(cwd, resolved_dst_path, strlen(cwd))) { + errno = 0; /* suppress missleading error prints */ + free(resolved_dst_path); + bb_perror_msg_and_die("path traversal detected: %s", + dst_name); + } + free(resolved_dst_path); + } else { + bb_perror_msg_and_die("cannot allocate memory for real path: %s", + dst_name); + } + } +#endif + if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { char *slash = strrchr(dst_name, '/'); if (slash) { diff --git a/testsuite/cpio.tests b/testsuite/cpio.tests index 85e746589..1c0b75297 100755 --- a/testsuite/cpio.tests +++ b/testsuite/cpio.tests @@ -154,6 +154,24 @@ testing "cpio -R with extract" \ " "" "" SKIP= +optional FEATURE_PATH_TRAVERSAL_PROTECTION +rm -rf cpio.testdir +mkdir -p cpio.testdir/prepare/inner +echo "file outside of destination was written" > cpio.testdir/prepare/dont_write +echo "data" > cpio.testdir/prepare/inner/to_extract +mkdir -p cpio.testdir/extract +testing "cpio extract file outside of destination" \ +"(cd cpio.testdir/prepare/inner && echo -e '../dont_write\nto_extract' | cpio -H newc --create) | +(cd cpio.testdir/extract && cpio -vi 2>&1); +echo \$?; +ls cpio.testdir/dont_write 2>&1" \ +"\ +cpio: path traversal detected: ../dont_write +1 +ls: cpio.testdir/dont_write: No such file or directory +" "" "" +SKIP= + # Clean up rm -rf cpio.testdir cpio.testdir2 2>/dev/null -- 2.44.0 From rasmus.villemoes at prevas.dk Mon Apr 29 15:46:23 2024 From: rasmus.villemoes at prevas.dk (Rasmus Villemoes) Date: Mon, 29 Apr 2024 17:46:23 +0200 Subject: test -w on r/o filesystems Message-ID: <141874b8-8484-4691-b776-bb49d26f9f70@prevas.dk> It seems that busybox' "test" returns the wrong result when applied to a R/O filesystem. ### Permissions "allow" write for root # ls -ld / drwxr-xr-x 15 root root 221 Apr 5 2011 / ### But the rootfs is (and can only be) mounted ro # mount | grep ' / ' /dev/mmcblk0p5 on / type squashfs (ro,noatime,errors=continue) ### With coreutils test # test -w / && echo Writable || echo Not writable Not writable ### With busybox test # busybox test -w / && echo Writable || echo Not writable Writable Rasmus From Christian.Franke at t-online.de Mon Apr 29 17:51:15 2024 From: Christian.Franke at t-online.de (Christian Franke) Date: Mon, 29 Apr 2024 19:51:15 +0200 Subject: test -w on r/o filesystems In-Reply-To: <141874b8-8484-4691-b776-bb49d26f9f70@prevas.dk> References: <141874b8-8484-4691-b776-bb49d26f9f70@prevas.dk> Message-ID: Rasmus Villemoes wrote: > It seems that busybox' "test" returns the wrong result when applied to a > R/O filesystem. > > ### Permissions "allow" write for root > # ls -ld / > drwxr-xr-x 15 root root 221 Apr 5 2011 / The rw-permission bits do not matter if the effective user id is root. Root has always rw-access (and x-access if any x-bit is set) if the filesystem is not R/O. > ### But the rootfs is (and can only be) mounted ro > # mount | grep ' / ' > /dev/mmcblk0p5 on / type squashfs (ro,noatime,errors=continue) > ### With coreutils test > # test -w / && echo Writable || echo Not writable > Not writable > ### With busybox test > # busybox test -w / && echo Writable || echo Not writable > Writable The 'test' implementation of gnu coreutils uses euidaccess() from gnulib. This usually calls a kernel function faccessat(), eaccess() or similar and only falls back to the traditional check (euid is root or the relevant w-bit is set) if none of these are available. The busybox implementation of euidaccess() only uses a simplified variant of the latter method. This cannot detect R/O mounts but the kernel functions possibly do. https://github.com/coreutils/gnulib/blob/master/lib/euidaccess.c BTW, the behavior of the builtin 'test' commands of various shells may also differ if the filesystem is R/O. -- Regards, Christian