aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-09-02 23:13:10 +0000
committerEric Andersen <andersen@codepoet.org>2004-09-02 23:13:10 +0000
commitfd7a4c8c2887187e901809d89997deefb8b99d97 (patch)
tree70ea04a5934546b070f3e0c403629fe4da7aa444
parent7b08cdd98cdf99b0d2bd622566e9288d44b17529 (diff)
downloadbusybox-w32-fd7a4c8c2887187e901809d89997deefb8b99d97.tar.gz
busybox-w32-fd7a4c8c2887187e901809d89997deefb8b99d97.tar.bz2
busybox-w32-fd7a4c8c2887187e901809d89997deefb8b99d97.zip
Jonas Holmberg from axis dot com writes:
This patch makes msh handle variable expansion within backticks more correctly. Current behaviour (wrong): -------------------------- BusyBox v1.00-rc3 (2004.08.26-11:51+0000) Built-in shell (msh) Enter 'help' for a list of built-in commands. $ A='`echo hello`' $ echo $A `echo hello` $ echo `echo $A` hello $ New behaviour (correct): ------------------------ BusyBox v1.00-rc3 (2004.08.26-11:51+0000) Built-in shell (msh) Enter 'help' for a list of built-in commands. $ A='`echo hello`' $ echo $A `echo hello` $ echo `echo $A` `echo hello` $ The current behaviour (wrong according to standards) was actually my fault. msh handles backticks by executing a subshell (which makes it work on MMU-less systems). Executing a subshell makes it hard to only expand variables once in the parent. Therefore I export all variables that will be expanded within the backticks and let the subshell handle the expansion instead. The bug was found while searching for security leaks in CGI-scripts. Current behaviour of msh makes it easy to expand backticks by mistake in $QUERY_STRING. I recommend appling the patch before release of bb 1.00. /Jonas
-rw-r--r--shell/msh.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/shell/msh.c b/shell/msh.c
index df4c3dab3..2fb0df739 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -299,7 +299,7 @@ static int rlookup(char *n);
299static struct wdblock *glob(char *cp, struct wdblock *wb); 299static struct wdblock *glob(char *cp, struct wdblock *wb);
300static int my_getc(int ec); 300static int my_getc(int ec);
301static int subgetc(int ec, int quoted); 301static int subgetc(int ec, int quoted);
302static char **makenv(int all); 302static char **makenv(int all, struct wdblock *wb);
303static char **eval(char **ap, int f); 303static char **eval(char **ap, int f);
304static int setstatus(int s); 304static int setstatus(int s);
305static int waitfor(int lastpid, int canintr); 305static int waitfor(int lastpid, int canintr);
@@ -3032,7 +3032,7 @@ forkexec(REGISTER struct op *t, int *pin, int *pout, int act, char **wp)
3032 if (wp[0] == NULL) 3032 if (wp[0] == NULL)
3033 _exit(0); 3033 _exit(0);
3034 3034
3035 cp = rexecve(wp[0], wp, makenv(0)); 3035 cp = rexecve(wp[0], wp, makenv(0, NULL));
3036 prs(wp[0]); 3036 prs(wp[0]);
3037 prs(": "); 3037 prs(": ");
3038 err(cp); 3038 err(cp);
@@ -3486,7 +3486,7 @@ struct op *t;
3486 signal(SIGINT, SIG_DFL); 3486 signal(SIGINT, SIG_DFL);
3487 signal(SIGQUIT, SIG_DFL); 3487 signal(SIGQUIT, SIG_DFL);
3488 } 3488 }
3489 cp = rexecve(t->words[0], t->words, makenv(0)); 3489 cp = rexecve(t->words[0], t->words, makenv(0, NULL));
3490 prs(t->words[0]); 3490 prs(t->words[0]);
3491 prs(": "); 3491 prs(": ");
3492 err(cp); 3492 err(cp);
@@ -3954,14 +3954,12 @@ static char **eval(char **ap, int f)
3954 * names in the dictionary. Keyword assignments 3954 * names in the dictionary. Keyword assignments
3955 * will already have been done. 3955 * will already have been done.
3956 */ 3956 */
3957static char **makenv(int all) 3957static char **makenv(int all, struct wdblock *wb)
3958{ 3958{
3959 REGISTER struct wdblock *wb;
3960 REGISTER struct var *vp; 3959 REGISTER struct var *vp;
3961 3960
3962 DBGPRINTF5(("MAKENV: enter, all=%d\n", all)); 3961 DBGPRINTF5(("MAKENV: enter, all=%d\n", all));
3963 3962
3964 wb = NULL;
3965 for (vp = vlist; vp; vp = vp->next) 3963 for (vp = vlist; vp; vp = vp->next)
3966 if (all || vp->status & EXPORT) 3964 if (all || vp->status & EXPORT)
3967 wb = addword(vp->name, wb); 3965 wb = addword(vp->name, wb);
@@ -4251,6 +4249,7 @@ int quoted;
4251 int ignore; 4249 int ignore;
4252 int ignore_once; 4250 int ignore_once;
4253 char *argument_list[4]; 4251 char *argument_list[4];
4252 struct wdblock *wb = NULL;
4254 4253
4255#if __GNUC__ 4254#if __GNUC__
4256 /* Avoid longjmp clobbering */ 4255 /* Avoid longjmp clobbering */
@@ -4323,22 +4322,47 @@ int quoted;
4323 src++; 4322 src++;
4324 } 4323 }
4325 4324
4326 vp = lookup(var_name); 4325 if (isalpha(*var_name)) {
4327 if (vp->value != null) 4326 /* let subshell handle it instead */
4328 value = (operator == '+') ? alt_value : vp->value; 4327
4329 else if (operator == '?') { 4328 char *namep = var_name;
4330 err(alt_value);
4331 return (0);
4332 } else if (alt_index && (operator != '+')) {
4333 value = alt_value;
4334 if (operator == '=')
4335 setval(vp, value);
4336 } else
4337 continue;
4338 4329
4339 while (*value && (count < LINELIM)) { 4330 *dest++ = '$';
4340 *dest++ = *value++; 4331 if (braces)
4341 count++; 4332 *dest++ = '{';
4333 while (*namep)
4334 *dest++ = *namep++;
4335 if (operator) {
4336 char *altp = alt_value;
4337 *dest++ = operator;
4338 while (*altp)
4339 *dest++ = *altp++;
4340 }
4341 if (braces)
4342 *dest++ = '}';
4343
4344 wb = addword(lookup(var_name)->name, wb);
4345 } else {
4346 /* expand */
4347
4348 vp = lookup(var_name);
4349 if (vp->value != null)
4350 value = (operator == '+') ?
4351 alt_value : vp->value;
4352 else if (operator == '?') {
4353 err(alt_value);
4354 return (0);
4355 } else if (alt_index && (operator != '+')) {
4356 value = alt_value;
4357 if (operator == '=')
4358 setval(vp, value);
4359 } else
4360 continue;
4361
4362 while (*value && (count < LINELIM)) {
4363 *dest++ = *value++;
4364 count++;
4365 }
4342 } 4366 }
4343 } else { 4367 } else {
4344 *dest++ = *src++; 4368 *dest++ = *src++;
@@ -4383,7 +4407,7 @@ int quoted;
4383 argument_list[2] = child_cmd; 4407 argument_list[2] = child_cmd;
4384 argument_list[3] = 0; 4408 argument_list[3] = 0;
4385 4409
4386 cp = rexecve(argument_list[0], argument_list, makenv(1)); 4410 cp = rexecve(argument_list[0], argument_list, makenv(1, wb));
4387 prs(argument_list[0]); 4411 prs(argument_list[0]);
4388 prs(": "); 4412 prs(": ");
4389 err(cp); 4413 err(cp);