Date: Friday, September 26, 2014 @ 05:33:18 Author: fyan Revision: 223013
upgpkg: bash 4.3.026-1 - removed funcdef-import.patch as it has been included upstream as bash43-025 patch - add bash43-026 patch to address CVE-2014-7169 (from http://www.openwall.com/lists/oss-security/2014/09/26/1) - add variables-affix.patch (from http://pkgs.fedoraproject.org/cgit/bash.git/tree/bash-4.2-cve-2014-7169-1.patch?id=6319f7c362cfe9062d7bbfec48650caa366da480) - add parser-oob-4.2.patch (from http://seclists.org/oss-sec/2014/q3/712) Added: bash/trunk/bash43-026 bash/trunk/parser-oob-4.2.patch bash/trunk/variables-affix.patch Modified: bash/trunk/PKGBUILD -----------------------+ PKGBUILD | 22 ++++-- bash43-026 | 60 ++++++++++++++++++ parser-oob-4.2.patch | 85 ++++++++++++++++++++++++++ variables-affix.patch | 155 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 315 insertions(+), 7 deletions(-) Modified: PKGBUILD =================================================================== --- PKGBUILD 2014-09-25 19:51:44 UTC (rev 223012) +++ PKGBUILD 2014-09-26 03:33:18 UTC (rev 223013) @@ -5,9 +5,9 @@ pkgname=bash _basever=4.3 -_patchlevel=024 +_patchlevel=026 pkgver=$_basever.$_patchlevel -pkgrel=2 +pkgrel=1 pkgdesc='The GNU Bourne Again shell' arch=('i686' 'x86_64') license=('GPL') @@ -25,10 +25,13 @@ system.bashrc system.bash_logout privmode-setuid-fail.patch - funcdef-import.patch) + # CVE-2014-7169 patch from http://www.openwall.com/lists/oss-security/2014/09/26/1 + bash43-026 + variables-affix.patch + parser-oob-4.2.patch) if [[ $((10#${_patchlevel})) -gt 0 ]]; then - for (( _p=1; _p<=$((10#${_patchlevel})); _p++ )); do + for (( _p=1; _p<=$((10#${_patchlevel}-1)); _p++ )); do # "-1" was added as workaround for not-published 026 patch) source=(${source[@]} http://ftp.gnu.org/gnu/bash/bash-$_basever-patches/bash${_basever//.}-$(printf "%03d" $_p){,.sig}) done fi @@ -44,8 +47,9 @@ # http://hmarco.org/bugs/bash_4.3-setuid-bug.html (FS#40663) patch -p0 -i ../privmode-setuid-fail.patch - # CVE-2014-6271 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271 - patch -p0 -i ../funcdef-import.patch + # CVE-2014-7169 patches + patch -p0 -i ../variables-affix.patch + patch -p0 -i ../parser-oob-4.2.patch } build() { @@ -89,7 +93,9 @@ '561949793177116b7be29a07c385ba8b' '472f536d7c9e8250dc4568ec4cfaf294' 'a577d42e38249d298d6a8d4bf2823883' - '231b04ccc931653b12244bcc0a4eea70' + '922578e2be7ed03729454e92ee8d3f3a' + '2ac173523d3437a0ab517ae4248d0a98' + '461145288c8ffbf05c0f90554b2aa885' '1ab682b4e36afa4cf1b426aa7ac81c0d' 'SKIP' '8fc22cf50ec85da00f6af3d66f7ddc1b' @@ -137,4 +143,6 @@ 'b3cb0d80fd0c47728264405cbb3b23c7' 'SKIP' 'b5ea5600942acceb4b6f07313d2de74e' + 'SKIP' + '193c06f578d38ffdbaebae9c51a7551f' 'SKIP') Added: bash43-026 =================================================================== --- bash43-026 (rev 0) +++ bash43-026 2014-09-26 03:33:18 UTC (rev 223013) @@ -0,0 +1,60 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.3 +Patch-ID: bash43-026 + +Bug-Reported-by: Tavis Ormandy <[email protected]> +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.3.25/parse.y 2014-07-30 10:14:31.000000000 -0400 +--- parse.y 2014-09-25 20:20:21.000000000 -0400 +*************** +*** 2954,2957 **** +--- 2954,2959 ---- + word_desc_to_read = (WORD_DESC *)NULL; + ++ eol_ungetc_lookahead = 0; ++ + current_token = '\n'; /* XXX */ + last_read_token = '\n'; +*** ../bash-4.3.25/y.tab.c 2014-07-30 10:14:32.000000000 -0400 +--- y.tab.c 2014-09-25 20:21:48.000000000 -0400 +*************** +*** 5266,5269 **** +--- 5266,5271 ---- + word_desc_to_read = (WORD_DESC *)NULL; + ++ eol_ungetc_lookahead = 0; ++ + current_token = '\n'; /* XXX */ + last_read_token = '\n'; +*************** +*** 8540,8542 **** + } + #endif /* HANDLE_MULTIBYTE */ +- +--- 8542,8543 ---- +*** ../bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500 +--- patchlevel.h 2014-03-20 20:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 25 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 26 + + #endif /* _PATCHLEVEL_H_ */ Added: parser-oob-4.2.patch =================================================================== --- parser-oob-4.2.patch (rev 0) +++ parser-oob-4.2.patch 2014-09-26 03:33:18 UTC (rev 223013) @@ -0,0 +1,85 @@ +--- ../bash-4.2-orig/parse.y 2014-09-25 13:07:59.218209276 +0200 ++++ parse.y 2014-09-25 15:26:52.813159810 +0200 +@@ -264,9 +264,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; +@@ -519,42 +531,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 + { +@@ -4757,7 +4769,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; + + Added: variables-affix.patch =================================================================== --- variables-affix.patch (rev 0) +++ variables-affix.patch 2014-09-26 03:33:18 UTC (rev 223013) @@ -0,0 +1,155 @@ +--- ../bash-4.2-orig/variables.c 2014-09-25 13:07:59.313209541 +0200 ++++ variables.c 2014-09-25 13:15:29.869420719 +0200 +@@ -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,36 +346,48 @@ + + /* 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, though we still allow them to be defined as shell + variables. */ +- 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 + { + if (temp_var = bind_variable (name, string, 0)) + { + VSETATTR (temp_var, (att_exported | att_imported | att_invisible)); + array_needs_making = 1; + } + last_command_exit_value = 1; + 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 ARRAY_EXPORT +@@ -2537,7 +2557,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; + +@@ -3388,22 +3408,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); + } + +@@ -3489,7 +3530,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]);
