From 9529115c4ce87d4faecd1c55e547162efe74d629 Mon Sep 17 00:00:00 2001 From: Kang-Che Sung Date: Wed, 4 Jan 2017 12:29:04 +0100 Subject: shell: clarify help text of CONFIG_{SH,BASH}_IS_* options Mention the behavior if user selects CONFIG_SH_IS_ASH but not CONFIG_ASH. We will be explicit that invocations like "busybox ash" will not work for such configuration. Also clarify help text of CONFIG_BASH_IS_* that bash compatibility in ash is not complete. (It shouldn't be anyway - ash can't support every bash quirk out there.) Signed-off-by: Kang-Che Sung Signed-off-by: Denys Vlasenko --- shell/Config.src | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/Config.src b/shell/Config.src index 7f5f67050..9bd493fed 100644 --- a/shell/Config.src +++ b/shell/Config.src @@ -17,9 +17,19 @@ choice config SH_IS_ASH depends on !NOMMU bool "ash" + help + Choose ash to be the shell executed by 'sh' name. + The ash code will be built into busybox. If you don't select + "ash" choice (CONFIG_ASH), this shell may only be invoked by + the name 'sh' (and not 'ash'). config SH_IS_HUSH bool "hush" + help + Choose hush to be the shell executed by 'sh' name. + The hush code will be built into busybox. If you don't select + "hush" choice (CONFIG_HUSH), this shell may only be invoked by + the name 'sh' (and not 'hush'). config SH_IS_NONE bool "none" @@ -31,7 +41,8 @@ choice default BASH_IS_NONE help Choose which shell you want to be executed by 'bash' alias. - The ash shell is the most bash compatible and full featured one. + The ash shell is the most bash compatible and full featured one, + although compatibility is far from being complete. Note that selecting this option does not switch on any bash compatibility code. It merely makes it possible to install @@ -46,9 +57,19 @@ choice config BASH_IS_ASH depends on !NOMMU bool "ash" + help + Choose ash to be the shell executed by 'bash' name. + The ash code will be built into busybox. If you don't select + "ash" choice (CONFIG_ASH), this shell may only be invoked by + the name 'bash' (and not 'ash'). config BASH_IS_HUSH bool "hush" + help + Choose hush to be the shell executed by 'bash' name. + The hush code will be built into busybox. If you don't select + "hush" choice (CONFIG_HUSH), this shell may only be invoked by + the name 'bash' (and not 'hush'). config BASH_IS_NONE bool "none" -- cgit v1.2.3-55-g6feb From 6cd0294725cf40a3ef0bb0a1dcc7a7044a85cbf5 Mon Sep 17 00:00:00 2001 From: Kang-Che Sung Date: Fri, 6 Jan 2017 17:02:03 +0100 Subject: ash: explicltly group ash options This would makes all ash options indented inside "ash" in menuconfig. It appears that menuconfig has a limit at tracking multiple dependency lines like this (it looks like a "diamond problem" but I'm not sure if it is): ---ASH <---------- / \ ASH_OPTIMIZE_FOR_SIZE !NOMMU <-*----SH_IS_ASH <----[OR] <--ASH_INTERNAL_GLOB \ / ASH_RANDOM_SUPPORT ---BASH_IS_ASH <-- [...] The kconfig-language document [1] states that: > If a menu entry somehow depends on the previous entry, it can be > made a submenu of it. First, the previous (parent) symbol must be > part of the dependency list and then one of these two conditions > must be true: > - the child entry must become invisible, if the parent is set to 'n' [BusyBox ash used to satisfy this, but no longer does] > - the child entry must only be visible, if the parent is visible [BusyBox ash configs actually satisfy this, but because of "diamond" above this might not be easily detected] So I found out a direct workaround: by making ash options explicitly depend on !NOMMU, we can tell menuconfig that rule 2 above is satisfied without any more tracking. --------------------- / \ !NOMMU <-*-----ASH <-------- \ \ \ \ ASH_OPTIMIZE_FOR_SIZE *---SH_IS_ASH <---[OR]-[AND] <--ASH_INTERNAL_GLOB \ / ASH_RANDOM_SUPPORT --BASH_IS_ASH <- [...] So all ash options would now be indented under "ash". [1] "Documentation/kbuild/kconfig-language.txt" in Linux kernel source Signed-off-by: Kang-Che Sung Signed-off-by: Denys Vlasenko --- shell/Config.src | 4 ++++ shell/ash.c | 7 +++++++ 2 files changed, 11 insertions(+) (limited to 'shell') diff --git a/shell/Config.src b/shell/Config.src index 9bd493fed..3545f05dd 100644 --- a/shell/Config.src +++ b/shell/Config.src @@ -80,6 +80,9 @@ endchoice INSERT +comment "Options common to all shells" +if ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH + config FEATURE_SH_MATH bool "POSIX math support" default y @@ -163,5 +166,6 @@ config FEATURE_SH_HISTFILESIZE to set shell history size. Note that its max value is capped by "History size" setting in library tuning section. +endif # Options common to all shells endmenu diff --git a/shell/ash.c b/shell/ash.c index 7c53946ce..aee3d419c 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -26,6 +26,11 @@ //config: shell (by Herbert Xu), which was created by porting the 'ash' shell //config: (written by Kenneth Almquist) from NetBSD. //config: +//config:# ash options +//config:# note: Don't remove !NOMMU part in the next line; it would break +//config:# menuconfig's indenting. +//config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH) +//config: //config:config ASH_OPTIMIZE_FOR_SIZE //config: bool "Optimize for size instead of speed" //config: default y @@ -140,6 +145,8 @@ //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH //config: help //config: Enable "check for new mail" function in the ash shell. +//config: +//config:endif # ash options //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) //applet:IF_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) -- cgit v1.2.3-55-g6feb From 86584e134eec1a81298149f8c04c77727f6dccb9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 7 Jan 2017 10:15:01 +0100 Subject: ash: fix open fds leaking in redirects. Closes 9561 commit e19923f6652a638ac39c84012e97f52cf5a7568e deleted clearredir() call in shellexec(): ash: [REDIR] Remove redundant CLOEXEC calls Upstream commit: Now that we're marking file descriptors as CLOEXEC in savefd, we no longer need to close them on exec or in setinputfd. but it missed one place where we don't set CLOEXEC. Fixing this. Signed-off-by: Denys Vlasenko --- shell/ash.c | 11 +++++++---- shell/ash_test/ash-redir/redir_leak.right | 6 ++++++ shell/ash_test/ash-redir/redir_leak.tests | 10 ++++++++++ shell/hush_test/hush-redir/redir_leak.right | 6 ++++++ shell/hush_test/hush-redir/redir_leak.tests | 10 ++++++++++ 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 shell/ash_test/ash-redir/redir_leak.right create mode 100755 shell/ash_test/ash-redir/redir_leak.tests create mode 100644 shell/hush_test/hush-redir/redir_leak.right create mode 100755 shell/hush_test/hush-redir/redir_leak.tests (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index aee3d419c..efb4615db 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -5433,11 +5433,11 @@ redirect(union node *redir, int flags) /* Careful to not accidentally "save" * to the same fd as right side fd in N>&M */ int minfd = right_fd < 10 ? 10 : right_fd + 1; +#if defined(F_DUPFD_CLOEXEC) + i = fcntl(fd, F_DUPFD_CLOEXEC, minfd); +#else i = fcntl(fd, F_DUPFD, minfd); -/* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds - * are closed in popredir() in the child, preventing them from leaking - * into child. (popredir() also cleans up the mess in case of failures) - */ +#endif if (i == -1) { i = errno; if (i != EBADF) { @@ -5452,6 +5452,9 @@ redirect(union node *redir, int flags) remember_to_close: i = CLOSED; } else { /* fd is open, save its copy */ +#if !defined(F_DUPFD_CLOEXEC) + fcntl(i, F_SETFD, FD_CLOEXEC); +#endif /* "exec fd>&-" should not close fds * which point to script file(s). * Force them to be restored afterwards */ diff --git a/shell/ash_test/ash-redir/redir_leak.right b/shell/ash_test/ash-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.right @@ -0,0 +1,6 @@ +4 +4 +4 +4 +4 +4 diff --git a/shell/ash_test/ash-redir/redir_leak.tests b/shell/ash_test/ash-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.tests @@ -0,0 +1,10 @@ +# Each of these should show only four lines: +# fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. +# This test detects bugs where redirects leave stray open fds. + +ls -1 /proc/self/fd | wc -l +ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l +ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l +echo "`ls -1 /proc/self/fd `" | wc -l +echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l +echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l diff --git a/shell/hush_test/hush-redir/redir_leak.right b/shell/hush_test/hush-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.right @@ -0,0 +1,6 @@ +4 +4 +4 +4 +4 +4 diff --git a/shell/hush_test/hush-redir/redir_leak.tests b/shell/hush_test/hush-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.tests @@ -0,0 +1,10 @@ +# Each of these should show only four lines: +# fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. +# This test detects bugs where redirects leave stray open fds. + +ls -1 /proc/self/fd | wc -l +ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l +ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l +echo "`ls -1 /proc/self/fd `" | wc -l +echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l +echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l -- cgit v1.2.3-55-g6feb