Embedded scripts require a shell to be present in the BusyBox
binary. Allow either ash or hush to be used for this purpose.
If both are enabled ash takes precedence.
The size of the binary is unchanged in the default configuration:
both ash and hush are present but support for embedded scripts
isn't compiled into hush.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The embedded script feature makes it easier to create applets with
duplicate names. Currently in such cases the build succeeds but
the resulting executable doesn't work as the developer intended.
Catch duplicate names when the applet tables are being generated
and make the build fail.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
- Force a rebuild if a script in applets_sh is changed.
- Move the dummy usage messages for custom applets to usage.h and
change the name from 'dummy' to 'scripted'.
- Hide an error from gen_build_files.sh if an embed directory exists
but is empty.
- Tidy up embedded_scripts script.
v2: Remove a couple of unnecessary tests in embedded_scripts, as
pointed out by Xabier Oneca.
Drop the stripping of comments.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The parser reads from an already freed memory location, thereby causing
unpredictable results, in the following situation:
- ENABLE_ASH_EXPAND_PRMT is enabled
- heredoc is being parsed
- command substitution is used within heredoc
Examples where this bug crops up are (PS2 is set to "> "):
$ cat <<EOF
> `echo abc`
> EOF
-sh: O: not found
$ cat <<EOF
> $(echo abc)
> EOF
-sh: {garbage}: not found
The presumable reason is that setprompt_if() causes a nested expansion when
ENABLE_ASH_EXPAND_PRMT is enabled, therefore leaving "wordtext" in an unusable
state. However, when parseheredoc() is called, "tokpushback" is non-zero, which
causes the next call to xxreadtoken() to return TWORD, causing the caller to
use the invalid "wordtoken" instead of reading the next valid token.
The call chain is:
list()
-> peektoken() [sets tokpushback to 1]
-> parseheredoc()
-> setprompt_if()
-> pushstackmark()
-> expandstr()
-> readtoken1()
[sets lasttoken to TWORD, wordtoken points to expanded prompt]
-> popstackmark() [invalidates wordtoken, leaves lasttoken as is]
-> readtoken1()
-> ...parsebackq
-> list()
-> andor()
-> pipeline()
-> readtoken()
-> xxreadtoken()
[tokpushback non-zero, reuse lasttoken and wordtext]
Note that in almost all other contexts, each call to setprompt_if() is preceded
by setting "tokpushback" to zero. One exception is "oldstyle" backquote parsing
in readtoken1(), but there "tokpushback" is reset afterwards. The other
exception is nlprompt(), but this function is only used within readtoken1()
(but in contexts where no nested calls to xxreadtoken() occur) and xxreadtoken()
(where "tokpushback" is guaranteed to be zero).
function old new delta
parseheredoc 124 131 +7
Signed-off-by: Christoph Schulz <develop@kristov.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Before:
Trying libraries: crypt m resolv
Library crypt is not needed, excluding it
Library m is needed, can't exclude it (yet)
Library resolv is needed, can't exclude it (yet)
Library m is needed, can't exclude it (yet)
Library resolv is needed, can't exclude it (yet)
Final link with: m resolv
After:
Trying libraries: crypt m resolv
Library crypt is not needed, excluding it
Library m is needed, can't exclude it (yet)
Library resolv is needed, can't exclude it (yet)
Final link with: m resolv
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The build process for embedded scripts didn't have consistent
support for saving output to a different directory.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Add an option to allow the content of embedded scripts to be
displayed. This includes applet scripts, custom scripts and the
.profile script.
function old new delta
busybox_main 624 701 +77
find_script_by_name - 24 +24
scripted_main 41 35 -6
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 101/-6) Total: 95 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
BusyBox has support for embedded shell scripts. Two types can be
distinguished: custom scripts and scripts implementing applets.
Custom scripts should be placed in the 'embed' directory at build
time. They are given a default applet configuration and appear
as applets to the user but no further configuration is possible.
Applet scripts are integrated with the BusyBox build system and
are intended to be used to ship standard applets that just happen
to be implemented as scripts. They can be configured at build time
and appear just like native applets.
Such scripts should be placed in the 'applets_sh' directory. A stub
C program should be written to provide the usual applet configuration
details and placed in a suitable subsystem directory. It may be
helpful to have a configuration option to enable any dependencies the
script requires: see the 'nologin' applet for an example.
function old new delta
scripted_main - 41 +41
applet_names 2773 2781 +8
applet_main 1600 1604 +4
i2cdetect_main 672 674 +2
applet_suid 100 101 +1
applet_install_loc 200 201 +1
applet_flags 100 101 +1
packed_usage 33180 33179 -1
tryexec 159 152 -7
evalcommand 1661 1653 -8
script_names 9 - -9
packed_scripts 123 114 -9
complete_cmd_dir_file 826 811 -15
shellexec 271 254 -17
find_command 1007 990 -17
busybox_main 642 624 -18
run_applet_and_exit 100 78 -22
find_script_by_name 51 - -51
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 6/9 up/down: 58/-174) Total: -116 bytes
text data bss dec hex filename
950034 477 7296 957807 e9d6f busybox_old
949918 477 7296 957691 e9cfb busybox_unstripped
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When a variable is unset by calling setvar(name, NULL, 0) the code
to initialise the new, empty variable fails to initialise the last
character of the string.
Attempts to read the contents of the unset variable will result
in the uninitialised character at the end of the string being
accessed.
For example, running BusyBox under Valgrind and unsetting PATH:
$ valgrind ./busybox_unstripped sh
==21249== Memcheck, a memory error detector
==21249== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21249== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==21249== Command: ./busybox_unstripped sh
==21249==
/data2/git/build_fix_8721 $ unset PATH
/data2/git/build_fix_8721 $ 0
==21249== Conditional jump or move depends on uninitialised value(s)
==21249== at 0x451371: path_advance (ash.c:2555)
==21249== by 0x456E22: find_command (ash.c:13407)
==21249== by 0x458425: evalcommand (ash.c:10139)
==21249== by 0x454CBC: evaltree (ash.c:9131)
==21249== by 0x456C80: cmdloop (ash.c:13164)
Closes https://bugs.busybox.net/show_bug.cgi?id=8721
v2: On the dash mailing list Harald van Dijk was kind enough to point
out a flaw in my reasoning and provide an alternative patch. Sadly
his patch adds 2 bytes of bloat. Using xzalloc to zero the whole
string gives a bloat of -3 bytes.
function old new delta
setvar 172 169 -3
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The HUSH_TICK configuration option enables command substitution,
not process substitution.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>