| Commit message (Collapse) | Author | Files | Lines |
|
Upstream commit a61d158d5 (stat: fix negative %X/%Y/%Z timestamps
after Y2038 on 32-bit builds) changed how timestamps are printed.
Update the code to use the correct format specifiers on Windows.
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
get_key() locates a key in two passes: j=0 walks to the start of the
START field, j=1 walks to the end of the END field. When END carries
an ENDCHAR (-kSTART,N.ENDCHAR), that char position is supposed to be
counted from the start of field N. Instead the code overwrote 'end'
with the raw parsed value, an offset from the very start of the line:
if (key->range[3]) {
end = key->range[3];
For END field 1 this happens to be the same thing, but for any later
field it is not. The result usually lands before 'start', which then
gets clamped to 'start', producing an empty key. Sort has an ASCII
whole-line fallback when keys tie, so it silently sorts by the whole
line instead of the requested key:
$ printf '%s\n' 'b:aa' 'a:ba' 'a:aa' | busybox sort -t : -k 2.1,2.1
a:aa
a:ba
b:aa
$ printf '%s\n' 'b:aa' 'a:ba' 'a:aa' | sort -t : -k 2.1,2.1
a:aa
b:aa
a:ba
Make the j=1 pass stop at the start of field N instead of its end when
ENDCHAR is given, one field-skip short of the usual pass, and add the
ENDCHAR offset from there. This mirrors how STARTCHAR is already
applied relative to the start of the START field. Verified against
several -k combinations (endchar past the field's own length, multiple
fields skipped, startchar and endchar together) matching GNU sort.
Add a regression test; the existing ENDCHAR test only exercises field
1, where the old absolute offset and the correct field-relative one
happen to coincide.
function old new delta
get_key 490 516 +26
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
With gcc-15.0.1:
function old new delta
tftpd_main 603 617 +14
expand_one_var 1923 1929 +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 20/0) Total: 20 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
function old new delta
expand_args 186 181 -5
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Suppresses a lot of selinux warnings.
This does not change the code.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
print_ascii() is intended to skip leading spaces before printing ATA
IDENTIFY strings, but the condition is inverted and skips non-space
characters instead.
As a result, left-justified strings such as serial numbers and firmware
revisions can be printed as empty, while strings containing embedded
spaces, such as model names, are truncated up to the first space.
Fix the condition so only leading spaces are skipped, and add a regression
test covering left-justified strings, embedded spaces, and leading-space
padding.
function old new delta
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0) Total: 0 bytes
Signed-off-by: Romain Guyard <foss@romainguyard.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
function old new delta
fmt_num 257 380 +123
.rodata 107332 107342 +10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 133/0) Total: 133 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
function old new delta
writeTarHeader 859 869 +10
Signed-off-by: Anton Skorup <anton.skorup@axis.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
When the awk program ends with \<newline> right after the last string
token, nextchar() eats the newline and then reads the terminating NUL
that xmalloc_read_with_initial_buf() appends, advancing past the end
of the buffer. The string-scan loop in next_token() then dereferences
one byte past the buffer (heap-buffer-overflow, READ of size 1).
Fix: test every nextchar() return for NULs.
Reproducer (ASan build):
awk 'BEGIN { print "string\
'
function old new delta
next_token 934 933 -1
Signed-off-by: Ediz <ediz.research@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
function old new delta
printf_llu - 35 +35
printf_lx - 30 +30
printf_lu - 30 +30
printf_s - 28 +28
printfs 28 - -28
print_statfs 338 260 -78
print_stat 858 761 -97
------------------------------------------------------------------------------
(add/remove: 4/1 grow/shrink: 0/2 up/down: 123/-203) Total: -80 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Introduce a utility function to always print `time_t` values using either
`long long` or `unsigned long long`, depending on whether `time_t` is
signed. This fixes the bug reported in [1].
Previously, `time_t` values were cast to `long`, which is a 32-bit value
on 32-bit builds.
[1]: https://lists.busybox.net/pipermail/busybox/2026-August/092413.html
function old new delta
print_stat 869 858 -11
Signed-off-by: Benjamin Robin <benjamin.robin@bootlin.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
The merge with upstream in commit 4afa250a0 accidentally
reintroduced one of the FAST_FUNC annotations removed in commit
99d22da0e (Remove FAST_FUNC from variadic functions).
Remove it again as it caused a 32-bit cross-compilation with gcc
to fail on Alma Linux 10.
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
When PROMPT_COMMAND is run the exit status of the last command
should be preserved so $? reports the correct value.
Adds 16 bytes.
(GitHub issue #615)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
Combining the verbose (-v) and extract-to-stdout (-O) options caused
verbose output and extracted file data to be interleaved unpredictably on
stdout. Verbose listing uses buffered stdio (printf()/puts()), while file
contents are written directly to the stdout file descriptor.
GNU tar also combines buffered verbose output with unbuffered writes for
"-vO", however, GNU tar writes verbose output to stderr, so the two streams
remain separate and consistent.
Fix this by making "tar xvO" send output to stderr.
function old new delta
header_verbose_list 244 279 +35
header_list 15 49 +34
get_header_tar 1764 1769 +5
header_verbose_list_ar 77 78 +1
get_header_ar 542 540 -2
get_header_cpio 959 948 -11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/2 up/down: 75/-13) Total: 62 bytes
Signed-off-by: Thorsten B <brehmt@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Commit f13f68288 (rpm2cpio: extract cpio even if compression is
not known) added an error message if the compression method was
unknown. When support for lzma was disabled this resulted in a
null pointer being passed to bb_error_msg().
The call to rpm_getstr0() to fetch the name of the compression
method shouldn't depend on lzma being supported.
This doesn't affect the size of a default build. In a build with
lzma disabled:
function old new delta
rpm2cpio_main 110 121 +11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 11/0) Total: 11 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
When the read built-in's '-n' option is used to limit the number
of characters read, backslashes should only be counted if the '-r'
option is also suppiled. This matches how bash behaves.
function old new delta
shell_builtin_read 1360 1358 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-2) Total: -2 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
This was already done on read() failure, why not on poll()?
Making it consistent.
function old new delta
shell_builtin_read 1318 1308 -10
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
GNU and BSD patch both handle patches which include the annotation
'\ No newline at end of file'. BusyBox patch doesn't, even though
its diff emits it.
Implement this feature and add some tests.
function old new delta
patch_main 1912 2002 +90
do_line 88 116 +28
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 118/0) Total: 118 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
If PROMPT_COMMAND is set early in execution, via the -c option or
in .profile, the shell segfaults when trying to print the prompt.
Moving the handling of PROMPT_COMMAND out of parsecmd() into
cmdloop() fixes this.
Adds 16-64 bytes.
(GitHub issue #615)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
Commit 4496f1338 (ash: limited support for PROMPT_COMMAND) didn't
cause the shell to exit if PROMPT_COMMAND exited. This is not how
bash behaves: PROMPT_COMMAND=exit really does cause the shell to exit.
Implement this.
Adds 0-16 bytes.
(GitHub issue #615)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
Bash supports the PROMPT_COMMAND variable as a way to run commands
just before the PS1 prompt is issued. Add a similar feature to
ash.
Unlike bash, ash doesn't support array variables so it's only
possible to set a single command to be run.
Adds 164-268 bytes.
(GitHub issue #615)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
Commit f7bcc977c (ash: make ctrl-c trap handling closer to upstream)
resulted in ctrl-c on the command line issuing an extra newline:
$ ^C
$
In the past this looked more like what bash does:
$ ^C
$
This is entirely cosmetic and the output from other shells may well
be different.
Adjust the code so the output looks more like bash in this particular
case.
Saves 36-72 bytes.
(GitHub issue #616)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
function old new delta
static.grep_longopts - 17 +17
packed_usage 36237 36243 +6
.rodata 107341 107332 -9
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 23/-9) Total: 14 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Recent changes mean there are now three places where calls to
stat(2) require the flags which control expensive operations to
be reset to their default values and back to their current setting.
It becomes useful to provide a function to handle this operation.
Also add tests to ensure this doesn't break the previous fix.
Saves 48 bytes.
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
For running files that are a proper Windows executable format, but
without an extension, this stat call could fail.
$ cp busybox.exe busybox_noext
$ ./busybox.exe find -name win32 -exec ./busybox_noext echo {} +
find: ./busybox_noext: Permission denied
|
|
Applied the same fix as previous, resetting the flags to default, then
restoring them afterwards.
This previously resulted in the following failing:
$ echo -e '#!/bin/sh\necho "$@"' >echo_sh
$ find -name win32 -exec ./echo_sh {} +
find: ./echo_sh: No such file or directory
|
|
Commit 158b6215a (ash: allow more than 64 background jobs) fixed
an issue in 'ash' for shells with more than 64 jobs.
There were a couple of problems:
- The test to break out of the for loop failed to take account of
pending_int and waitcmd_int.
- The code could incorrectly identify the process with index
258 (WAIT_TIMEOUT, 0x102) as having terminated.
Rearrange the code to fix these issues and to save a few bytes.
Saves 80-96 bytes.
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
Commit 194f95902 (xargs: fix handling for more than 64 processes)
fixed some errors in the code to handle more than 64 processes.
On reflection, why bother with that code in the first place?
The '-P 0' option already limits the number of processes to 64.
Letting the user choose a larger value seems unnecessary.
Apply the limit in all cases and remove the code to handle more
than MAXIMUM_WAIT_OBJECTS processes.
Saves 64-80 bytes.
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
WaitForMultipleObjects only allows waiting on 64 handles or threads at a
time (MAXIMUM_WAIT_OBJECTS), meaning that we instead need to do multiple
calls to it, each with only that many items.
For example:
for i in $(seq 1 70); do echo $i; sleep 10 & done
Signed-off-by: Morgan Bartlett <mjmouse9999@gmail.com>
|
|
The previous code wouldn't ever work as the condition was around the
wrong way. Also fixed an off-by-one error under the loop.
Signed-off-by: Morgan Bartlett <mjmouse9999@gmail.com>
|
|
The principal change is to replace four separate arrays (one for
pids and three for time values) with a single array of structs.
There are some other minor adjustments.
Saves 96-144 bytes.
(GitHub PR #609)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
time is unknown.
|
|
Windows aggressively reuses PIDs of exited processes. When a new irrelevant process gets assigned the former PID of the parent of an orphaned process, `pkill -P`, `pgrep -P`, `ps -o ppid` sees the new process as the parent of the orphaned process, and PPID of the orphan is no longer 1. So in theory, all `pkill -P`, `pgrep -P` calls are potentially dangerous and possible to kill an innocent process which outlives its parent.
This issue is already discussed in various Internet communities:
- https://stackoverflow.com/questions/6593003/how-can-i-reliably-check-whether-one-windows-process-is-the-parent-of-another-in
- https://web.archive.org/web/20140701081232/https://www.sapphiresteel.com/Blog/Killing-Trees-the-Windows-way
Comparing process creation times seems a feasible mitigation that should almost always work (though not theoretically sound).
The executable is added 512 bytes after the patch.
|
|
position
cp --remove-destination was broken by commit 56bbbfae "cp: implement -n"
function old new delta
cp_main 527 533 +6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
function old new delta
cp_main 514 527 +13
.rodata 107332 107341 +9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 22/0) Total: 22 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Replace a call to 'FindNextFileA()' in 'get_reparse_tag()'.
This has no effect on the standard builds. Builds with the UTF-8
manifest included save 4-8 bytes as this removes the only remaining
call to 'FindNextFileA()'.
(GitHub issue #506)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
In certain circumstances 'FindNextFileA()' can fail because the
legacy DOS 8.3 short name doesn't fit in the buffer supplied.
This can be avoided by using 'FindFirstFileExA()' instead, but
with a setting that isn't available on Windows XP.
- The problem doesn't arise in the standard 32 and 64 bit builds,
so no change is required.
- Builds with full Unicode support target platforms which have the
required setting. They can use 'FindFirstFileExA()' unconditionally,
at the cost of 36-56 bytes.
- Builds which include the UTF-8 manifest but which are allowed
to run on systems prior to Windows 10 need to check whether they
need to call 'FindFirstFileExA()' at runtime. This adds 100 bytes.
(GitHub issue #506)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
Since 2022 the 'xxd' which comes with 'vim' has allowed the
combination of options '-p -c 0' as a way to request output on
a single line. Details:
https://github.com/vim/vim/pull/9524
Add this feature to the BusyBox 'xxd' applet.
Adds 64 bytes.
(GitHub issue #610)
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
function old new delta
readfields 442 437 -5
printfields 462 457 -5
join_main 843 760 -83
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-93) Total: -93 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
function old new delta
join_main - 843 +843
printfields - 462 +462
readfields - 442 +442
.rodata 107120 107332 +212
packed_usage 36078 36237 +159
applet_names 2870 2875 +5
applet_main 1652 1656 +4
------------------------------------------------------------------------------
(add/remove: 4/0 grow/shrink: 4/0 up/down: 2127/0) Total: 2127 bytes
text data bss dec hex filename
1080964 555 4992 1086511 10942f busybox_old
1083091 555 4992 1088638 109c7e busybox_unstripped
v2: Add a missing return statement which broke the '-t' option.
Thanks to Roberto A. Foglietta for pointing this out.
Signed-off-by: Morgan Bartlett <mjmouse9999@gmail.com>
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
The 'make' applet failed to build with FEATURE_CLEAN_UP enabled.
Add an early declaration of freerules() to avoid this.
This doesn't affect the default builds.
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
ifsfree() does not only release allocated ifsregion nodes; it also clears
the global IFS region state used by ifsbreakup(). If argstr() raises an
error while expanding an argument, ash longjmps out of expandarg() before
that cleanup runs, leaving stale IFS split offsets behind.
A later expansion can reuse the stack for a shorter string. ifsbreakup()
then sees the stale IFS state, trusts the old offsets, and can walk past
the current stack block before dereferencing p.
Follow dash's root-cause fix: when an expansion-related handler catches
EXERROR and continues, restore the handler and call ifsfree(). Apply
the cleanup to redirectsafe(), expandstr(), and evaltree().
Upstream commit:
Date: Mon Dec 5 23:02:01 2022 +0800
expand: Add ifsfree to expand to fix a logic error that causes a buffer over-read
On Mon, Jun 20, 2022 at 02:27:10PM -0400, Alex Gorinson wrote:
> Due to a logic error in the ifsbreakup function in expand.c if a
> heredoc and normal command is run one after the other by means of a
> semi-colon, when the second command drops into ifsbreakup the command
> will be evaluated with the ifslastp/ifsfirst struct that was set when
> the here doc was evaluated. This results in a buffer over-read that
> can leak the program's heap, stack, and arena addresses which can be
> used to beat ASLR.
>
> Steps to Reproduce:
> First bug:
> cmd args: ~/exampleDir/example> dash
> $ M='AAAAAAAAAAAAAAAAA' <note: 17 A's>
> $ q00(){
> $ <<000;echo
> $ ${D?$M$M$M$M$M$M} <note: 6 $M's>
> $ 000
> $ }
> $ q00 <note: After the q00 is typed in, the leak
> should be echo'd out; this works with ash, busybox ash, and dash and
> with all option args.>
>
> Patch:
> Adding the following to expand.c will fix both bugs in one go.
> (Thank you to Harald van Dijk and Michael Greenberg for doing the
> heavy lifting for this patch!)
> ==========================
> --- a/src/expand.c
> +++ b/src/expand.c
> @@ -859,6 +859,7 @@
> if (discard)
> return -1;
>
> +ifsfree();
> sh_error("Bad substitution");
> }
>
> @@ -1739,6 +1740,7 @@
> } else
> msg = umsg;
> }
> +ifsfree();
> sh_error("%.*s: %s%s", end - var - 1, var, msg, tail);
> }
> ==========================
Thanks for the report!
I think it's better to add the ifsfree() call to the exception
handling path as other sh_error calls may trigger this too.
function old new delta
restore_handler_expandarg - 33 +33
evaltree 725 711 -14
static.redirectsafe 141 124 -17
expandstr 262 242 -20
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/3 up/down: 36/-45) Total: -18 bytes
Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
It broke single-character splitting
|
|
function old new delta
awk_printf 1381 1387 +6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
|
Add a freelines() function to free the line data associated with
an FDAT struct. This has no effect in the default build but saves
48-64 bytes if FEATURE_CLEAN_UP is enabled.
Change the type of the 'first' flag in readfields() to be consistent
with that in printfields().
The 'lines' array should be freed for each FDAT struct during clean
up, as it was before I broke it.
Signed-off-by: Ron Yorston <rmy@pobox.com>
|