summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess <joeyh@debian.org>2006-05-07 14:47:16 -0700
committerPhilip Hands <phil@hands.com>2022-09-02 17:10:44 +0200
commitd86f5b778d33da9f5d0f12509d4731a4d5ee127d (patch)
tree86db16c6091782f8300ccebd5e704912d285637b
parent95e1404a5adb82069851941c7d75676ddd9aef11 (diff)
busybox sh sets but does not export PATH
Bug-Debian: https://bugs.debian.org/329406 Bug-Debian: https://bugs.debian.org/679377 Forwarded: no This patch exports $PATH variable from busybox ash by default, even if no "export PATH" statement has been processed. No other shell (dash, bash, ...) does this: $ env - /bin/bash -c /usr/bin/env PWD=/tmp SHLVL=1 _=/usr/bin/env But after #329406, busybox ash started exporting this variable by default. This change hasn't been sent upstream. However, this turned out to be problematic, after many upstream changes, busybox started segfaulting in interesting and difficult to debug environments - like, when running as pid=1 in initramfs. This is recorded in #679377. The problem was that PATH was the only variable marked to be exported by default, and this is done by this very patch. Other exported variables were always malloc'ed, but this one was not. But when ash executes applets marked as NOEXEC, it does not really execute anything, it forks and runs the applet's main() function, clearing and setting up the environment as it'd do for any other command. There, it is assumed that all exported variables were malloc'ed, and the function (tryexec() in ash.c) writes to the place in exported variable where the equal sign is. So, if ash inherited no PATH variable and the default is used, the code will try to write \0 into a constant location, and we'll get a segfault. The whole patch is probably not needed (because other shells don't export PATH by default), but at this stage (during wheezy freeze) we can't just drop it, since it may lead to some random breakage in some other random place (and that'll be another very difficult to debug issue). So instead of dropping the patch, we modify the PATH variable to be stored in non-const location, ie, to be writable. It is safe, since the only place which actually modifies this variable (after the first half of this patch) is the awk main function, during setup, it restores the overridden byte after touching it, and it is a "terminal" applet, ie, it exits after doing its work. For wheezy+1, we should drop this patch completely. For now, we will live with this simple and ugly forkaround. /mjt Gbp-Pq: Name shell-ash-export-HOME.patch
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/messages.c2
-rw-r--r--shell/ash.c2
3 files changed, 3 insertions, 3 deletions
diff --git a/include/libbb.h b/include/libbb.h
index a48782832..4949aba6b 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2264,7 +2264,7 @@ extern const char bb_busybox_exec_path[] ALIGN1;
#define BB_ADDITIONAL_PATH ""
#endif
#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH
-extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
+extern char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
#define bb_default_root_path (bb_PATH_root_path + sizeof("PATH"))
/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
* but I want to save a few bytes here:
diff --git a/libbb/messages.c b/libbb/messages.c
index 6914d5701..a25d10378 100644
--- a/libbb/messages.c
+++ b/libbb/messages.c
@@ -31,7 +31,7 @@ const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
* but I want to save a few bytes here. Check libbb.h before changing! */
-const char bb_PATH_root_path[] ALIGN1 = BB_PATH_ROOT_PATH;
+char bb_PATH_root_path[] ALIGN1 = BB_PATH_ROOT_PATH;
//const int const_int_1 = 1;
diff --git a/shell/ash.c b/shell/ash.c
index 827643808..aeccd9aa9 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2134,7 +2134,7 @@ static const struct {
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL" , changemail },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH" , changemail },
#endif
- { VSTRFIXED|VTEXTFIXED , bb_PATH_root_path, changepath },
+ { VSTRFIXED|VTEXTFIXED|VEXPORT, bb_PATH_root_path, changepath },
{ VSTRFIXED|VTEXTFIXED , "PS1=$ " , NULL },
{ VSTRFIXED|VTEXTFIXED , "PS2=> " , NULL },
{ VSTRFIXED|VTEXTFIXED , "PS4=+ " , NULL },