# HG changeset patch # User Stefan Teleman # Date 1415808125 28800 # Node ID 32e84fd7641c8ec2f5a010fdb0edae103d99171e # Parent 1240b4c4e38d2e6316171bb0e23a0f17eaa638eb 19701904 problem in UTILITY/BASH diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/bash41-012.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/bash/patches/bash41-012.patch Wed Nov 12 08:02:05 2014 -0800 @@ -0,0 +1,104 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-012 + +Bug-Reported-by: Stephane Chazelas +Bug-Reference-ID: +Bug-Reference-URL: + +Bug-Description: + +Under certain circumstances, bash will execute user code while processing the +environment for exported function definitions. + +Patch (apply with `patch -p0'): + +*** ../bash-4.1.11/builtins/common.h 2009-12-22 16:30:42.000000000 -0500 +--- builtins/common.h 2014-09-16 19:27:38.000000000 -0400 +*************** +*** 36,39 **** +--- 36,41 ---- + + /* Flags for describe_command, shared between type.def and command.def */ ++ #define SEVAL_FUNCDEF 0x080 /* only allow function definitions */ ++ #define SEVAL_ONECMD 0x100 /* only allow a single command */ + #define CDESC_ALL 0x001 /* type -a */ + #define CDESC_SHORTDESC 0x002 /* command -V */ +*** ../bash-4.1.11/builtins/evalstring.c 2009-10-17 21:18:50.000000000 -0400 +--- builtins/evalstring.c 2014-09-16 19:27:38.000000000 -0400 +*************** +*** 262,265 **** +--- 262,273 ---- + struct fd_bitmap *bitmap; + ++ if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def) ++ { ++ internal_warning ("%s: ignoring function definition attempt", from_file); ++ should_jump_to_top_level = 0; ++ last_result = last_command_exit_value = EX_BADUSAGE; ++ break; ++ } ++ + bitmap = new_fd_bitmap (FD_BITMAP_SIZE); + begin_unwind_frame ("pe_dispose"); +*************** +*** 322,325 **** +--- 330,336 ---- + dispose_fd_bitmap (bitmap); + discard_unwind_frame ("pe_dispose"); ++ ++ if (flags & SEVAL_ONECMD) ++ break; + } + } +*** ../bash-4.1.11/variables.c 2010-03-26 12:15:39.000000000 -0400 +--- variables.c 2014-09-16 19:27:38.000000000 -0400 +*************** +*** 348,357 **** + strcpy (temp_string + char_index + 1, string); + +! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST); +! +! /* Ancient backwards compatibility. Old versions of bash exported +! functions like name()=() {...} */ +! if (name[char_index - 1] == ')' && name[char_index - 2] == '(') +! name[char_index - 2] = '\0'; + + if (temp_var = find_function (name)) +--- 348,355 ---- + strcpy (temp_string + char_index + 1, string); + +! /* Don't import function names that are invalid identifiers from the +! environment. */ +! if (legal_identifier (name)) +! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); + + if (temp_var = find_function (name)) +*************** +*** 362,369 **** + else + report_error (_("error importing function definition for `%s'"), name); +- +- /* ( */ +- if (name[char_index - 1] == ')' && name[char_index - 2] == '\0') +- name[char_index - 2] = '('; /* ) */ + } + #if defined (ARRAY_VARS) +--- 360,363 ---- +*** ../bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 11 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 12 + + #endif /* _PATCHLEVEL_H_ */ diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/bash41-013.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/bash/patches/bash41-013.patch Wed Nov 12 08:02:05 2014 -0800 @@ -0,0 +1,43 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-013 + +Bug-Reported-by: Tavis Ormandy +Bug-Reference-ID: +Bug-Reference-URL: http://twitter.com/taviso/statuses/514887394294652929 + +Bug-Description: + +Under certain circumstances, bash can incorrectly save a lookahead character and +return it on a subsequent call, even when reading a new line. + +Patch (apply with `patch -p0'): + +*** ../bash-4.1.12/parse.y 2011-02-24 19:41:01.000000000 -0500 +--- parse.y 2014-09-25 16:13:57.000000000 -0400 +*************** +*** 2812,2815 **** +--- 2812,2817 ---- + word_desc_to_read = (WORD_DESC *)NULL; + ++ eol_ungetc_lookahead = 0; ++ + current_token = '\n'; /* XXX */ + last_read_token = '\n'; +*** ../bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 12 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 13 + + #endif /* _PATCHLEVEL_H_ */ diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/bash41-014.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/bash/patches/bash41-014.patch Wed Nov 12 08:02:05 2014 -0800 @@ -0,0 +1,217 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-014 + +Bug-Reported-by: Florian Weimer +Bug-Reference-ID: +Bug-Reference-URL: + +Bug-Description: + +This patch changes the encoding bash uses for exported functions to avoid +clashes with shell variables and to avoid depending only on an environment +variable's contents to determine whether or not to interpret it as a shell +function. + +Patch (apply with `patch -p0'): + +*** ../bash-4.1.13/variables.c 2014-09-16 19:27:38.000000000 -0400 +--- variables.c 2014-09-27 20:57:46.000000000 -0400 +*************** +*** 80,83 **** +--- 80,88 ---- + #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0') + ++ #define BASHFUNC_PREFIX "BASH_FUNC_" ++ #define BASHFUNC_PREFLEN 10 /* == strlen(BASHFUNC_PREFIX */ ++ #define BASHFUNC_SUFFIX "%%" ++ #define BASHFUNC_SUFFLEN 2 /* == strlen(BASHFUNC_SUFFIX) */ ++ + extern char **environ; + +*************** +*** 269,273 **** + static void dispose_temporary_env __P((sh_free_func_t *)); + +! static inline char *mk_env_string __P((const char *, const char *)); + static char **make_env_array_from_var_list __P((SHELL_VAR **)); + static char **make_var_export_array __P((VAR_CONTEXT *)); +--- 274,278 ---- + static void dispose_temporary_env __P((sh_free_func_t *)); + +! static inline char *mk_env_string __P((const char *, const char *, int)); + static char **make_env_array_from_var_list __P((SHELL_VAR **)); + static char **make_var_export_array __P((VAR_CONTEXT *)); +*************** +*** 339,357 **** + /* If exported function, define it now. Don't import functions from + the environment in privileged mode. */ +! if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4)) + { + string_length = strlen (string); +! temp_string = (char *)xmalloc (3 + string_length + char_index); + +! strcpy (temp_string, name); +! temp_string[char_index] = ' '; +! strcpy (temp_string + char_index + 1, string); + + /* Don't import function names that are invalid identifiers from the + environment. */ +! if (legal_identifier (name)) +! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); + +! if (temp_var = find_function (name)) + { + VSETATTR (temp_var, (att_exported|att_imported)); +--- 344,373 ---- + /* If exported function, define it now. Don't import functions from + the environment in privileged mode. */ +! if (privmode == 0 && read_but_dont_execute == 0 && +! STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN) && +! STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN) && +! STREQN ("() {", string, 4)) + { ++ size_t namelen; ++ char *tname; /* desired imported function name */ ++ ++ namelen = char_index - BASHFUNC_PREFLEN - BASHFUNC_SUFFLEN; ++ ++ tname = name + BASHFUNC_PREFLEN; /* start of func name */ ++ tname[namelen] = '\0'; /* now tname == func name */ ++ + string_length = strlen (string); +! temp_string = (char *)xmalloc (namelen + string_length + 2); + +! memcpy (temp_string, tname, namelen); +! temp_string[namelen] = ' '; +! memcpy (temp_string + namelen + 1, string, string_length + 1); + + /* Don't import function names that are invalid identifiers from the + environment. */ +! if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname))) +! parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); + +! if (temp_var = find_function (tname)) + { + VSETATTR (temp_var, (att_exported|att_imported)); +*************** +*** 359,363 **** + } + else +! report_error (_("error importing function definition for `%s'"), name); + } + #if defined (ARRAY_VARS) +--- 375,382 ---- + } + else +! report_error (_("error importing function definition for `%s'"), tname); +! +! /* Restore original suffix */ +! tname[namelen] = BASHFUNC_SUFFIX[0]; + } + #if defined (ARRAY_VARS) +*************** +*** 2520,2524 **** + + INVALIDATE_EXPORTSTR (var); +! var->exportstr = mk_env_string (name, value); + + array_needs_making = 1; +--- 2539,2543 ---- + + INVALIDATE_EXPORTSTR (var); +! var->exportstr = mk_env_string (name, value, 0); + + array_needs_making = 1; +*************** +*** 3339,3357 **** + + static inline char * +! mk_env_string (name, value) + const char *name, *value; + { +! int name_len, value_len; +! char *p; + + name_len = strlen (name); + value_len = STRLEN (value); +! p = (char *)xmalloc (2 + name_len + value_len); +! strcpy (p, name); +! p[name_len] = '='; + if (value && *value) +! strcpy (p + name_len + 1, value); + else +! p[name_len + 1] = '\0'; + return (p); + } +--- 3358,3397 ---- + + static inline char * +! mk_env_string (name, value, isfunc) + const char *name, *value; ++ int isfunc; + { +! size_t name_len, value_len; +! char *p, *q; + + name_len = strlen (name); + value_len = STRLEN (value); +! +! /* If we are exporting a shell function, construct the encoded function +! name. */ +! if (isfunc && value) +! { +! p = (char *)xmalloc (BASHFUNC_PREFLEN + name_len + BASHFUNC_SUFFLEN + value_len + 2); +! q = p; +! memcpy (q, BASHFUNC_PREFIX, BASHFUNC_PREFLEN); +! q += BASHFUNC_PREFLEN; +! memcpy (q, name, name_len); +! q += name_len; +! memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN); +! q += BASHFUNC_SUFFLEN; +! } +! else +! { +! p = (char *)xmalloc (2 + name_len + value_len); +! memcpy (p, name, name_len); +! q = p + name_len; +! } +! +! q[0] = '='; + if (value && *value) +! memcpy (q + 1, value, value_len + 1); + else +! q[1] = '\0'; +! + return (p); + } +*************** +*** 3439,3443 **** + using the cached exportstr... */ + list[list_index] = USE_EXPORTSTR ? savestring (value) +! : mk_env_string (var->name, value); + + if (USE_EXPORTSTR == 0) +--- 3479,3483 ---- + using the cached exportstr... */ + list[list_index] = USE_EXPORTSTR ? savestring (value) +! : mk_env_string (var->name, value, function_p (var)); + + if (USE_EXPORTSTR == 0) +*** ../bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 13 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 14 + + #endif /* _PATCHLEVEL_H_ */ diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/bash41-015.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/bash/patches/bash41-015.patch Wed Nov 12 08:02:05 2014 -0800 @@ -0,0 +1,173 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-015 + +Bug-Reported-by: Florian Weimer +Bug-Reference-ID: +Bug-Reference-URL: + +Bug-Description: + +There are two local buffer overflows in parse.y that can cause the shell +to dump core when given many here-documents attached to a single command +or many nested loops. + +Patch (apply with `patch -p0'): + +*** ../bash-4.1.14/parse.y 2014-09-27 12:18:25.000000000 -0400 +--- parse.y 2014-09-30 19:36:03.000000000 -0400 +*************** +*** 168,171 **** +--- 168,174 ---- + static int reserved_word_acceptable __P((int)); + static int yylex __P((void)); ++ ++ static void push_heredoc __P((REDIRECT *)); ++ static char *mk_alexpansion __P((char *)); + static int alias_expand_token __P((char *)); + static int time_command_acceptable __P((void)); +*************** +*** 262,266 **** + /* Variables to manage the task of reading here documents, because we need to + defer the reading until after a complete command has been collected. */ +! static REDIRECT *redir_stack[10]; + int need_here_doc; + +--- 265,271 ---- + /* Variables to manage the task of reading here documents, because we need to + defer the reading until after a complete command has been collected. */ +! #define HEREDOC_MAX 16 +! +! static REDIRECT *redir_stack[HEREDOC_MAX]; + int need_here_doc; + +*************** +*** 304,308 **** + index is decremented after a case, select, or for command is parsed. */ + #define MAX_CASE_NEST 128 +! static int word_lineno[MAX_CASE_NEST]; + static int word_top = -1; + +--- 309,313 ---- + index is decremented after a case, select, or for command is parsed. */ + #define MAX_CASE_NEST 128 +! static int word_lineno[MAX_CASE_NEST+1]; + static int word_top = -1; + +*************** +*** 517,521 **** + redir.filename = $2; + $$ = make_redirection (source, r_reading_until, redir, 0); +! redir_stack[need_here_doc++] = $$; + } + | NUMBER LESS_LESS WORD +--- 522,526 ---- + redir.filename = $2; + $$ = make_redirection (source, r_reading_until, redir, 0); +! push_heredoc ($$); + } + | NUMBER LESS_LESS WORD +*************** +*** 524,528 **** + redir.filename = $3; + $$ = make_redirection (source, r_reading_until, redir, 0); +! redir_stack[need_here_doc++] = $$; + } + | REDIR_WORD LESS_LESS WORD +--- 529,533 ---- + redir.filename = $3; + $$ = make_redirection (source, r_reading_until, redir, 0); +! push_heredoc ($$); + } + | REDIR_WORD LESS_LESS WORD +*************** +*** 531,535 **** + redir.filename = $3; + $$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN); +! redir_stack[need_here_doc++] = $$; + } + | LESS_LESS_MINUS WORD +--- 536,540 ---- + redir.filename = $3; + $$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN); +! push_heredoc ($$); + } + | LESS_LESS_MINUS WORD +*************** +*** 538,542 **** + redir.filename = $2; + $$ = make_redirection (source, r_deblank_reading_until, redir, 0); +! redir_stack[need_here_doc++] = $$; + } + | NUMBER LESS_LESS_MINUS WORD +--- 543,547 ---- + redir.filename = $2; + $$ = make_redirection (source, r_deblank_reading_until, redir, 0); +! push_heredoc ($$); + } + | NUMBER LESS_LESS_MINUS WORD +*************** +*** 545,549 **** + redir.filename = $3; + $$ = make_redirection (source, r_deblank_reading_until, redir, 0); +! redir_stack[need_here_doc++] = $$; + } + | REDIR_WORD LESS_LESS_MINUS WORD +--- 550,554 ---- + redir.filename = $3; + $$ = make_redirection (source, r_deblank_reading_until, redir, 0); +! push_heredoc ($$); + } + | REDIR_WORD LESS_LESS_MINUS WORD +*************** +*** 552,556 **** + redir.filename = $3; + $$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN); +! redir_stack[need_here_doc++] = $$; + } + | LESS_LESS_LESS WORD +--- 557,561 ---- + redir.filename = $3; + $$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN); +! push_heredoc ($$); + } + | LESS_LESS_LESS WORD +*************** +*** 2508,2511 **** +--- 2513,2531 ---- + static int esacs_needed_count; + ++ static void ++ push_heredoc (r) ++ REDIRECT *r; ++ { ++ if (need_here_doc >= HEREDOC_MAX) ++ { ++ last_command_exit_value = EX_BADUSAGE; ++ need_here_doc = 0; ++ report_syntax_error (_("maximum here-document count exceeded")); ++ reset_parser (); ++ exit_shell (last_command_exit_value); ++ } ++ redir_stack[need_here_doc++] = r; ++ } ++ + void + gather_here_documents () +*** ../bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 14 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 15 + + #endif /* _PATCHLEVEL_H_ */ diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/bash41-016.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/bash/patches/bash41-016.patch Wed Nov 12 08:02:05 2014 -0800 @@ -0,0 +1,59 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-016 + +Bug-Reported-by: Michal Zalewski +Bug-Reference-ID: +Bug-Reference-URL: + +Bug-Description: + +When bash is parsing a function definition that contains a here-document +delimited by end-of-file (or end-of-string), it leaves the closing delimiter +uninitialized. This can result in an invalid memory access when the parsed +function is later copied. + +Patch (apply with `patch -p0'): + +*** ../bash-4.1.15/make_cmd.c 2009-09-11 17:26:12.000000000 -0400 +--- make_cmd.c 2014-10-02 11:29:35.000000000 -0400 +*************** +*** 690,693 **** +--- 690,694 ---- + temp->redirector = source; + temp->redirectee = dest_and_filename; ++ temp->here_doc_eof = 0; + temp->instruction = instruction; + temp->flags = 0; +*** ../bash-4.1.15/copy_cmd.c 2009-09-11 16:28:02.000000000 -0400 +--- copy_cmd.c 2014-10-02 11:29:35.000000000 -0400 +*************** +*** 127,131 **** + case r_reading_until: + case r_deblank_reading_until: +! new_redirect->here_doc_eof = savestring (redirect->here_doc_eof); + /*FALLTHROUGH*/ + case r_reading_string: +--- 127,131 ---- + case r_reading_until: + case r_deblank_reading_until: +! new_redirect->here_doc_eof = redirect->here_doc_eof ? savestring (redirect->here_doc_eof) : 0; + /*FALLTHROUGH*/ + case r_reading_string: +*** ../bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 15 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 16 + + #endif /* _PATCHLEVEL_H_ */ diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/bash41-017.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/bash/patches/bash41-017.patch Wed Nov 12 08:02:05 2014 -0800 @@ -0,0 +1,132 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-017 + +Bug-Reported-by: Michal Zalewski +Bug-Reference-ID: +Bug-Reference-URL: + +Bug-Description: + +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. + +Patch (apply with `patch -p0'): + +*** ../bash-4.1.16/builtins/evalstring.c 2014-09-16 19:27:38.000000000 -0400 +--- builtins/evalstring.c 2014-10-04 15:08:26.000000000 -0400 +*************** +*** 262,271 **** + struct fd_bitmap *bitmap; + +! if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def) + { +! internal_warning ("%s: ignoring function definition attempt", from_file); +! should_jump_to_top_level = 0; +! last_result = last_command_exit_value = EX_BADUSAGE; +! break; + } + +--- 262,284 ---- + struct fd_bitmap *bitmap; + +! if (flags & SEVAL_FUNCDEF) + { +! 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; +! } + } + +*************** +*** 332,336 **** + + if (flags & SEVAL_ONECMD) +! break; + } + } +--- 345,352 ---- + + if (flags & SEVAL_ONECMD) +! { +! reset_parser (); +! break; +! } + } + } +*** ../bash-4.1.16/parse.y 2014-09-30 19:36:03.000000000 -0400 +--- parse.y 2014-10-04 15:08:26.000000000 -0400 +*************** +*** 2410,2413 **** +--- 2410,2423 ---- + } + ++ 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. */ +*************** +*** 3809,3814 **** + restore_parser_state (&ps); + reset_parser (); +! if (interactive) +! token_to_read = 0; + + /* Need to find how many characters parse_and_execute consumed, update +--- 3819,3824 ---- + restore_parser_state (&ps); + reset_parser (); +! +! token_to_read = 0; + + /* Need to find how many characters parse_and_execute consumed, update +*** ../bash-4.1.16/shell.h 2009-08-14 16:32:52.000000000 -0400 +--- shell.h 2014-10-04 15:08:26.000000000 -0400 +*************** +*** 164,167 **** +--- 164,169 ---- + + /* 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 *)); +*** ../bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 16 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 17 + + #endif /* _PATCHLEVEL_H_ */ diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/funcdef-import-4.1-CVE-2014-6271.patch --- a/components/bash/patches/funcdef-import-4.1-CVE-2014-6271.patch Mon Nov 10 14:45:35 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -# Patch is from the bash project. -# It is currently embargo'ed (as of 2014-02-23). -# It will become an official bash patch once the embargo is lifted. -*** ../bash-4.1.11/builtins/common.h 2009-12-22 16:30:42.000000000 -0500 ---- builtins/common.h 2014-09-16 19:27:38.000000000 -0400 -*************** -*** 36,39 **** ---- 36,41 ---- - - /* Flags for describe_command, shared between type.def and command.def */ -+ #define SEVAL_FUNCDEF 0x080 /* only allow function definitions */ -+ #define SEVAL_ONECMD 0x100 /* only allow a single command */ - #define CDESC_ALL 0x001 /* type -a */ - #define CDESC_SHORTDESC 0x002 /* command -V */ -*** ../bash-4.1.11/builtins/evalstring.c 2009-10-17 21:18:50.000000000 -0400 ---- builtins/evalstring.c 2014-09-16 19:27:38.000000000 -0400 -*************** -*** 262,265 **** ---- 262,273 ---- - struct fd_bitmap *bitmap; - -+ if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def) -+ { -+ internal_warning ("%s: ignoring function definition attempt", from_file); -+ should_jump_to_top_level = 0; -+ last_result = last_command_exit_value = EX_BADUSAGE; -+ break; -+ } -+ - bitmap = new_fd_bitmap (FD_BITMAP_SIZE); - begin_unwind_frame ("pe_dispose"); -*************** -*** 322,325 **** ---- 330,336 ---- - dispose_fd_bitmap (bitmap); - discard_unwind_frame ("pe_dispose"); -+ -+ if (flags & SEVAL_ONECMD) -+ break; - } - } -*** ../bash-4.1.11/variables.c 2010-03-26 12:15:39.000000000 -0400 ---- variables.c 2014-09-16 19:27:38.000000000 -0400 -*************** -*** 348,357 **** - strcpy (temp_string + char_index + 1, string); - -! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST); -! -! /* Ancient backwards compatibility. Old versions of bash exported -! functions like name()=() {...} */ -! if (name[char_index - 1] == ')' && name[char_index - 2] == '(') -! name[char_index - 2] = '\0'; - - if (temp_var = find_function (name)) ---- 348,355 ---- - strcpy (temp_string + char_index + 1, string); - -! /* Don't import function names that are invalid identifiers from the -! environment. */ -! if (legal_identifier (name)) -! parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); - - if (temp_var = find_function (name)) -*************** -*** 362,369 **** - else - report_error (_("error importing function definition for `%s'"), name); -- -- /* ( */ -- if (name[char_index - 1] == ')' && name[char_index - 2] == '\0') -- name[char_index - 2] = '('; /* ) */ - } - #if defined (ARRAY_VARS) ---- 360,363 ---- - diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/parse.y-CVE-2014-7169.patch --- a/components/bash/patches/parse.y-CVE-2014-7169.patch Mon Nov 10 14:45:35 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -# Patch is from Chet Ramey (Bash Project Lead); -# http://www.openwall.com/lists/oss-security/2014/09/25/10 -# This will become an official bash patch. -*** ../bash-20140912/parse.y 2014-08-26 15:09:42.000000000 -0400 ---- parse.y 2014-09-24 22:47:28.000000000 -0400 -*************** -*** 2959,2962 **** ---- 2959,2964 ---- - word_desc_to_read = (WORD_DESC *)NULL; - -+ eol_ungetc_lookahead = 0; -+ - current_token = '\n'; /* XXX */ - last_read_token = '\n'; - diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/parser-oob-4.1.patch --- a/components/bash/patches/parser-oob-4.1.patch Mon Nov 10 14:45:35 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -# Patch Origin: http://www.openwall.com/lists/oss-security/2014/09/26/2 -# Patch is from Red Hat Security. -# Assigned CVE-2014-7186 and CVE-2014-7187 -# CVSS Score: 4.6 ---- ../bash-4.1.orig/parse.y 2014-09-25 08:10:49.809021000 -0700 -+++ parse.y 2014-09-25 11:33:15.596573700 -0700 -@@ -261,9 +261,21 @@ - - /* Variables to manage the task of reading here documents, because we need to - defer the reading until after a complete command has been collected. */ --static REDIRECT *redir_stack[10]; -+static REDIRECT **redir_stack; - int need_here_doc; - -+/* Pushes REDIR onto redir_stack, resizing it as needed. */ -+static void -+push_redir_stack (REDIRECT *redir) -+{ -+ /* Guard against oveflow. */ -+ if (need_here_doc + 1 > INT_MAX / sizeof (*redir_stack)) -+ abort (); -+ redir_stack = xrealloc (redir_stack, -+ (need_here_doc + 1) * sizeof (*redir_stack)); -+ redir_stack[need_here_doc++] = redir; -+} -+ - /* Where shell input comes from. History expansion is performed on each - line when the shell is interactive. */ - static char *shell_input_line = (char *)NULL; -@@ -516,42 +528,42 @@ - source.dest = 0; - redir.filename = $2; - $$ = make_redirection (source, r_reading_until, redir, 0); -- redir_stack[need_here_doc++] = $$; -+ push_redir_stack ($$); - } - | NUMBER LESS_LESS WORD - { - source.dest = $1; - redir.filename = $3; - $$ = make_redirection (source, r_reading_until, redir, 0); -- redir_stack[need_here_doc++] = $$; -+ push_redir_stack ($$); - } - | REDIR_WORD LESS_LESS WORD - { - source.filename = $1; - redir.filename = $3; - $$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN); -- redir_stack[need_here_doc++] = $$; -+ push_redir_stack ($$); - } - | LESS_LESS_MINUS WORD - { - source.dest = 0; - redir.filename = $2; - $$ = make_redirection (source, r_deblank_reading_until, redir, 0); -- redir_stack[need_here_doc++] = $$; -+ push_redir_stack ($$); - } - | NUMBER LESS_LESS_MINUS WORD - { - source.dest = $1; - redir.filename = $3; - $$ = make_redirection (source, r_deblank_reading_until, redir, 0); -- redir_stack[need_here_doc++] = $$; -+ push_redir_stack ($$); - } - | REDIR_WORD LESS_LESS_MINUS WORD - { - source.filename = $1; - redir.filename = $3; - $$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN); -- redir_stack[need_here_doc++] = $$; -+ push_redir_stack ($$); - } - | LESS_LESS_LESS WORD - { -@@ -4677,7 +4689,7 @@ - case CASE: - case SELECT: - case FOR: -- if (word_top < MAX_CASE_NEST) -+ if ((word_top + 1) < MAX_CASE_NEST) - word_top++; - word_lineno[word_top] = line_number; - break; diff -r 1240b4c4e38d -r 32e84fd7641c components/bash/patches/variables-affix-4.1.patch --- a/components/bash/patches/variables-affix-4.1.patch Mon Nov 10 14:45:35 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -# Patch Origin: http://www.openwall.com/lists/oss-security/2014/09/25/32 -# Patch is from Red Hat Security. -# CVE-2014-7619 -# CVSS Score:10.0 -# This is an update to the previously released patchset for the same -# vulnerability. The previous patch did NOT cover all possible attack -# vectors. ---- ../bash-4.1.orig/variables.c 2014-09-25 08:10:49.920709400 -0700 -+++ variables.c 2014-09-25 11:59:38.642742000 -0700 -@@ -268,7 +268,7 @@ - static void propagate_temp_var __P((PTR_T)); - static void dispose_temporary_env __P((sh_free_func_t *)); - --static inline char *mk_env_string __P((const char *, const char *)); -+static inline char *mk_env_string __P((const char *, const char *, int)); - static char **make_env_array_from_var_list __P((SHELL_VAR **)); - static char **make_var_export_array __P((VAR_CONTEXT *)); - static char **make_func_export_array __P((void)); -@@ -301,6 +301,14 @@ - #endif - } - -+/* Prefix and suffix for environment variable names which contain -+ shell functions. */ -+#define FUNCDEF_PREFIX "BASH_FUNC_" -+#define FUNCDEF_PREFIX_LEN (strlen (FUNCDEF_PREFIX)) -+#define FUNCDEF_SUFFIX "()" -+#define FUNCDEF_SUFFIX_LEN (strlen (FUNCDEF_SUFFIX)) -+ -+ - /* Initialize the shell variables from the current environment. - If PRIVMODE is nonzero, don't import functions from ENV or - parse $SHELLOPTS. */ -@@ -338,27 +346,39 @@ - - /* If exported function, define it now. Don't import functions from - the environment in privileged mode. */ -- if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4)) -- { -- string_length = strlen (string); -- temp_string = (char *)xmalloc (3 + string_length + char_index); -+ if (privmode == 0 && read_but_dont_execute == 0 -+ && STREQN (FUNCDEF_PREFIX, name, FUNCDEF_PREFIX_LEN) -+ && STREQ (name + char_index - FUNCDEF_SUFFIX_LEN, FUNCDEF_SUFFIX) -+ && STREQN ("() {", string, 4)) -+ { -+ size_t name_length -+ = char_index - (FUNCDEF_PREFIX_LEN + FUNCDEF_SUFFIX_LEN); -+ char *temp_name = name + FUNCDEF_PREFIX_LEN; -+ /* Temporarily remove the suffix. */ -+ temp_name[name_length] = '\0'; - -- strcpy (temp_string, name); -- temp_string[char_index] = ' '; -- strcpy (temp_string + char_index + 1, string); -+ string_length = strlen (string); -+ temp_string = (char *)xmalloc (name_length + 1 + string_length + 1); -+ memcpy (temp_string, temp_name, name_length); -+ temp_string[name_length] = ' '; -+ memcpy (temp_string + name_length + 1, string, string_length + 1); - - /* Don't import function names that are invalid identifiers from the - environment. */ -- if (legal_identifier (name)) -- parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); -+ if (legal_identifier (temp_name)) -+ parse_and_execute (temp_string, temp_name, -+ SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); - -- if (temp_var = find_function (name)) -+ if (temp_var = find_function (temp_name)) - { - VSETATTR (temp_var, (att_exported|att_imported)); - array_needs_making = 1; - } - else - report_error (_("error importing function definition for `%s'"), name); -+ -+ /* Restore the original suffix. */ -+ temp_name[name_length] = FUNCDEF_SUFFIX[0]; - } - #if defined (ARRAY_VARS) - # if 0 -@@ -2515,7 +2535,7 @@ - var->context = variable_context; /* XXX */ - - INVALIDATE_EXPORTSTR (var); -- var->exportstr = mk_env_string (name, value); -+ var->exportstr = mk_env_string (name, value, 0); - - array_needs_making = 1; - -@@ -3333,22 +3353,43 @@ - /* */ - /* **************************************************************** */ - -+/* Returns the string NAME=VALUE if !FUNCTIONP or if VALUE == NULL (in -+ which case it is treated as empty). Otherwise, decorate NAME with -+ FUNCDEF_PREFIX and FUNCDEF_SUFFIX, and return a string of the form -+ FUNCDEF_PREFIX NAME FUNCDEF_SUFFIX = VALUE (without spaces). */ - static inline char * --mk_env_string (name, value) -+mk_env_string (name, value, functionp) - const char *name, *value; -+ int functionp; - { -- int name_len, value_len; -- char *p; -+ size_t name_len, value_len; -+ char *p, *q; - - name_len = strlen (name); - value_len = STRLEN (value); -- p = (char *)xmalloc (2 + name_len + value_len); -- strcpy (p, name); -- p[name_len] = '='; -+ if (functionp && value != NULL) -+ { -+ p = (char *)xmalloc (FUNCDEF_PREFIX_LEN + name_len + FUNCDEF_SUFFIX_LEN -+ + 1 + value_len + 1); -+ q = p; -+ memcpy (q, FUNCDEF_PREFIX, FUNCDEF_PREFIX_LEN); -+ q += FUNCDEF_PREFIX_LEN; -+ memcpy (q, name, name_len); -+ q += name_len; -+ memcpy (q, FUNCDEF_SUFFIX, FUNCDEF_SUFFIX_LEN); -+ q += FUNCDEF_SUFFIX_LEN; -+ } -+ else -+ { -+ p = (char *)xmalloc (name_len + 1 + value_len + 1); -+ memcpy (p, name, name_len); -+ q = p + name_len; -+ } -+ q[0] = '='; - if (value && *value) -- strcpy (p + name_len + 1, value); -+ memcpy (q + 1, value, value_len + 1); - else -- p[name_len + 1] = '\0'; -+ q[1] = '\0'; - return (p); - } - -@@ -3434,7 +3475,7 @@ - /* Gee, I'd like to get away with not using savestring() if we're - using the cached exportstr... */ - list[list_index] = USE_EXPORTSTR ? savestring (value) -- : mk_env_string (var->name, value); -+ : mk_env_string (var->name, value, function_p (var)); - - if (USE_EXPORTSTR == 0) - SAVE_EXPORTSTR (var, list[list_index]);