aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Zalewski <lcamtuf@coredump.cx>2014-10-10 11:16:06 +0100
committerPaul Kocialkowski <contact@paulk.fr>2014-11-16 11:43:09 +0100
commit80df778bb8f868423dfe5fc9847238eee8d0a764 (patch)
tree59d45ed476618e369899aaf1252f5ffcbb4df87e
parent2190a70e6324494accf7747d2aa9f5e8702d875c (diff)
downloadexternal_bash-replicant-4.2-0003.zip
external_bash-replicant-4.2-0003.tar.gz
external_bash-replicant-4.2-0003.tar.bz2
bugfix: bash executing code following func defHEADreplicant-4.2-0004replicant-4.2-0003replicant-4.2
This is an upstream bugfix (with slight alterations): Patch-ID: bash42-053 A combination of nested command substitutions and function importing from the environment can cause bash to execute code appearing in the environment variable value following the function definition. Change-Id: I660e59c76d0d50de52d48a0d399fe1dfef3bded8
-rw-r--r--builtins/evalstring.c28
-rw-r--r--parse.y14
-rw-r--r--shell.h2
-rw-r--r--y.tab.c13
4 files changed, 47 insertions, 10 deletions
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
index 61f57fc..c2bce74 100644
--- a/builtins/evalstring.c
+++ b/builtins/evalstring.c
@@ -261,12 +261,25 @@ parse_and_execute (string, from_file, flags)
{
struct fd_bitmap *bitmap;
- if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
+ if (flags & SEVAL_FUNCDEF)
{
- internal_warning ("%s: ignoring function definition attempt", from_file);
- should_jump_to_top_level = 0;
- last_result = last_command_exit_value = EX_BADUSAGE;
- break;
+ char *x;
+
+ /* If the command parses to something other than a straight
+ function definition, or if we have not consumed the entire
+ string, or if the parser has transformed the function
+ name (as parsing will if it begins or ends with shell
+ whitespace, for example), reject the attempt */
+ if (command->type != cm_function_def ||
+ ((x = parser_remaining_input ()) && *x) ||
+ (STREQ (from_file, command->value.Function_def->name->word) == 0))
+ {
+ internal_warning (_("%s: ignoring function definition attempt"), from_file);
+ should_jump_to_top_level = 0;
+ last_result = last_command_exit_value = EX_BADUSAGE;
+ reset_parser ();
+ break;
+ }
}
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
@@ -331,7 +344,10 @@ parse_and_execute (string, from_file, flags)
discard_unwind_frame ("pe_dispose");
if (flags & SEVAL_ONECMD)
- break;
+ {
+ reset_parser ();
+ break;
+ }
}
}
else
diff --git a/parse.y b/parse.y
index b3c17bc..b4ef178 100644
--- a/parse.y
+++ b/parse.y
@@ -2433,6 +2433,16 @@ shell_ungetc (c)
eol_ungetc_lookahead = c;
}
+char *
+parser_remaining_input ()
+{
+ if (shell_input_line == 0)
+ return 0;
+ if (shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len)
+ return '\0'; /* XXX */
+ return (shell_input_line + shell_input_line_index);
+}
+
#ifdef INCLUDE_UNUSED
/* Back the input pointer up by one, effectively `ungetting' a character. */
static void
@@ -3883,8 +3893,8 @@ xparse_dolparen (base, string, indp, flags)
restore_parser_state (&ps);
reset_parser ();
- if (interactive)
- token_to_read = 0;
+
+ token_to_read = 0;
/* Need to find how many characters parse_and_execute consumed, update
*indp, if flags != 0, copy the portion of the string parsed into RET
diff --git a/shell.h b/shell.h
index 92685e1..a643d80 100644
--- a/shell.h
+++ b/shell.h
@@ -167,5 +167,7 @@ typedef struct _sh_parser_state_t {
} sh_parser_state_t;
/* Let's try declaring these here. */
+extern char *parser_remaining_input __P((void));
+
extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
extern void restore_parser_state __P((sh_parser_state_t *));
diff --git a/y.tab.c b/y.tab.c
index 677960f..f72f81e 100644
--- a/y.tab.c
+++ b/y.tab.c
@@ -4746,6 +4746,16 @@ shell_ungetc (c)
eol_ungetc_lookahead = c;
}
+char *
+parser_remaining_input ()
+{
+ if (shell_input_line == 0)
+ return 0;
+ if (shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len)
+ return '\0'; /* XXX */
+ return (shell_input_line + shell_input_line_index);
+}
+
#ifdef INCLUDE_UNUSED
/* Back the input pointer up by one, effectively `ungetting' a character. */
static void
@@ -6196,8 +6206,7 @@ xparse_dolparen (base, string, indp, flags)
restore_parser_state (&ps);
reset_parser ();
- if (interactive)
- token_to_read = 0;
+ token_to_read = 0;
/* Need to find how many characters parse_and_execute consumed, update
*indp, if flags != 0, copy the portion of the string parsed into RET