mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 07:43:07 +02:00
commit bash-20141003 snapshot
This commit is contained in:
+86
-5
@@ -6790,7 +6790,8 @@ subst.c
|
||||
----
|
||||
variables.c
|
||||
- initialize_shell_variables: when importing function definitions from
|
||||
environment, use SEVAL_ONECMD flag for parse_and_execute
|
||||
environment, use SEVAL_ONECMD flag for parse_and_execute. Part of
|
||||
CVE-2014-6271
|
||||
|
||||
builtins/evalstring.c
|
||||
- parse_and_execute: if SEVAL_ONECMD flag set, return immediately after
|
||||
@@ -6812,11 +6813,12 @@ parse.y
|
||||
parse.y
|
||||
- push_heredoc: new function, pushes a here-doc redirection onto
|
||||
redir_stack handling overflow of redir_stack. Exits on overflow.
|
||||
Original fix from Florian Weimer <fweimer@redhat.com>
|
||||
Original fix from Florian Weimer <fweimer@redhat.com>. Fix for
|
||||
CVE-2014-7186
|
||||
- change straight assignments to redir_stack to call push_redir
|
||||
- add one to size of word_lineno stack to avoid off-by-one error
|
||||
below in read_token_word. Overflow just results in line numbers
|
||||
being wrong
|
||||
being wrong. Fix for CVE-2014-7187
|
||||
|
||||
9/27
|
||||
----
|
||||
@@ -6846,7 +6848,86 @@ copy_cmd.c
|
||||
- copy_redirects: before calling savestring on here_doc_eof, make
|
||||
sure it's not NULL (it could have been the result of a here
|
||||
document delimited by EOF or EOS). Fixes bug reported by
|
||||
Michal Zalewski <lcamtuf@coredump.cx>.
|
||||
Michal Zalewski <lcamtuf@coredump.cx>. Fix for CVE-2014-6277
|
||||
|
||||
make_cmd.c
|
||||
- make_redirection: initialize here_doc_eof member to NULL
|
||||
- make_redirection: initialize here_doc_eof member to NULL. Rest of
|
||||
fix for CVE-2014-6277
|
||||
|
||||
9/29
|
||||
----
|
||||
parse.y
|
||||
- current_input_line_state: return a sh_input_line_state_t containing
|
||||
the current shell_input_line and its index and size variables
|
||||
|
||||
shell.h
|
||||
- current_input_line_state: extern declaration
|
||||
|
||||
builtins/evalstring.c
|
||||
- parse_and_execute: call reset_parser() before returning if
|
||||
SEVAL_ONECMD set. Fixes bug reported by Michal Zalewski
|
||||
<lcamtuf@coredump.cx> and designated CVE-2014-6278
|
||||
- parse_and_execute: if we parse a function definition when
|
||||
SEVAL_FUNCDEF is set, but don't consume the entire passed string,
|
||||
throw an error, reset the parser, and return. Part of fix for
|
||||
CVE-2014-6278
|
||||
- parse_and_execute: if parsing the shell function definition when
|
||||
SEVAL_FUNCDEF is set transforms the function name (e.g., if it
|
||||
begins with a newline or begins or ends with whitespace), throw
|
||||
an error, reset the parser, and return. Fixes bug reported by
|
||||
Eric Kobrin <ekobrin@akamai.com>
|
||||
|
||||
10/2
|
||||
----
|
||||
jobs.c
|
||||
- bgp_prune: don't do anything if bgpids.npid == 0 or bgpids.list == NULL.
|
||||
This can happen if something gets run before the job control framework
|
||||
is initialized. Bug report from <mancha1@zoho.com>
|
||||
|
||||
10/3
|
||||
----
|
||||
parse.y
|
||||
- xparse_dolparen: don't set token_to_read to newline after calling
|
||||
parse_string() and cleaning up when the shell is not interactive. This
|
||||
makes the parser thing it's ok to read new commands even if it's not in
|
||||
a state where that should be possible. Underlying fix for bug reported
|
||||
by Michal Zalewski <lcamtuf@coredump.cx> and designated CVE-6278
|
||||
- parser_remaining_input: new function, returns the portion of
|
||||
shell_input_line that hasn't yet been read
|
||||
- current_input_line_state: removed
|
||||
|
||||
shell.h
|
||||
- parser_remaining_input: extern declaration
|
||||
- current_input_line_state: removed
|
||||
|
||||
builtins/evalstring.c
|
||||
- parse_and_execute: change code that checks whether parse_command has
|
||||
consumed the entire passed string when SEVAL_FUNCDEF is used to use
|
||||
parser_remaining_input instead of messing around with (new)
|
||||
current_input_line_state. Part of fix for CVE-2014-6278
|
||||
|
||||
variables.c
|
||||
- initialize_shell_variables: if we don't call parse_and_execute, free the
|
||||
temporary string, since parse_and_execute won't. Report and fix from
|
||||
Eric Kobrin <ekobrin@akamai.com>
|
||||
|
||||
10/4
|
||||
----
|
||||
print_cmd.c
|
||||
- print_function_def: when in posix mode, print shell function
|
||||
definitions as posix specifies them, without the leading
|
||||
`function' keyword
|
||||
|
||||
general.c
|
||||
- exportable_function_name: return 1 if the passed string can be
|
||||
added to the environment as an exported function name. Currently
|
||||
prohibits function names containing `/' and `=' from being
|
||||
exported
|
||||
|
||||
general.h
|
||||
- exportable_function_name: extern declaration
|
||||
|
||||
builtins/setattr.def
|
||||
- set_or_show_attributes: if exporting a function with export -f,
|
||||
call exportable_function_name to determine whether the function
|
||||
should be exported; don't export function if it returns 0
|
||||
|
||||
+74
-4
@@ -6790,7 +6790,8 @@ subst.c
|
||||
----
|
||||
variables.c
|
||||
- initialize_shell_variables: when importing function definitions from
|
||||
environment, use SEVAL_ONECMD flag for parse_and_execute
|
||||
environment, use SEVAL_ONECMD flag for parse_and_execute. Part of
|
||||
CVE-2014-6271
|
||||
|
||||
builtins/evalstring.c
|
||||
- parse_and_execute: if SEVAL_ONECMD flag set, return immediately after
|
||||
@@ -6812,11 +6813,12 @@ parse.y
|
||||
parse.y
|
||||
- push_heredoc: new function, pushes a here-doc redirection onto
|
||||
redir_stack handling overflow of redir_stack. Exits on overflow.
|
||||
Original fix from Florian Weimer <fweimer@redhat.com>
|
||||
Original fix from Florian Weimer <fweimer@redhat.com>. Fix for
|
||||
CVE-2014-7186
|
||||
- change straight assignments to redir_stack to call push_redir
|
||||
- add one to size of word_lineno stack to avoid off-by-one error
|
||||
below in read_token_word. Overflow just results in line numbers
|
||||
being wrong
|
||||
being wrong. Fix for CVE-2014-7187
|
||||
|
||||
9/27
|
||||
----
|
||||
@@ -6846,4 +6848,72 @@ copy_cmd.c
|
||||
- copy_redirects: before calling savestring on here_doc_eof, make
|
||||
sure it's not NULL (it could have been the result of a here
|
||||
document delimited by EOF or EOS). Fixes bug reported by
|
||||
Michal Zalewski <lcamtuf@coredump.cx>.
|
||||
Michal Zalewski <lcamtuf@coredump.cx>. Fix for CVE-2014-6277
|
||||
|
||||
make_cmd.c
|
||||
- make_redirection: initialize here_doc_eof member to NULL. Rest of
|
||||
fix for CVE-2014-6277
|
||||
|
||||
9/29
|
||||
----
|
||||
parse.y
|
||||
- current_input_line_state: return a sh_input_line_state_t containing
|
||||
the current shell_input_line and its index and size variables
|
||||
|
||||
shell.h
|
||||
- current_input_line_state: extern declaration
|
||||
|
||||
builtins/evalstring.c
|
||||
- parse_and_execute: call reset_parser() before returning if
|
||||
SEVAL_ONECMD set. Fixes bug reported by Michal Zalewski
|
||||
<lcamtuf@coredump.cx> and designated CVE-2014-6278
|
||||
- parse_and_execute: if we parse a function definition when
|
||||
SEVAL_FUNCDEF is set, but don't consume the entire passed string,
|
||||
throw an error, reset the parser, and return. Part of fix for
|
||||
CVE-2014-6278
|
||||
- parse_and_execute: if parsing the shell function definition when
|
||||
SEVAL_FUNCDEF is set transforms the function name (e.g., if it
|
||||
begins with a newline or begins or ends with whitespace), throw
|
||||
an error, reset the parser, and return. Fixes bug reported by
|
||||
Eric Kobrin <ekobrin@akamai.com>
|
||||
|
||||
10/2
|
||||
----
|
||||
jobs.c
|
||||
- bgp_prune: don't do anything if bgpids.npid == 0 or bgpids.list == NULL.
|
||||
This can happen if something gets run before the job control framework
|
||||
is initialized. Bug report from <mancha1@zoho.com>
|
||||
|
||||
10/3
|
||||
----
|
||||
parse.y
|
||||
- xparse_dolparen: don't set token_to_read to newline after calling
|
||||
parse_string() and cleaning up when the shell is not interactive. This
|
||||
makes the parser thing it's ok to read new commands even if it's not in
|
||||
a state where that should be possible. Underlying fix for bug reported
|
||||
by Michal Zalewski <lcamtuf@coredump.cx> and designated CVE-6278
|
||||
- parser_remaining_input: new function, returns the portion of
|
||||
shell_input_line that hasn't yet been read
|
||||
- current_input_line_state: removed
|
||||
|
||||
shell.h
|
||||
- parser_remaining_input: extern declaration
|
||||
- current_input_line_state: removed
|
||||
|
||||
builtins/evalstring.c
|
||||
- parse_and_execute: change code that checks whether parse_command has
|
||||
consumed the entire passed string when SEVAL_FUNCDEF is used to use
|
||||
parser_remaining_input instead of messing around with (new)
|
||||
current_input_line_state. Part of fix for CVE-2014-6278
|
||||
|
||||
variables.c
|
||||
- initialize_shell_variables: if we don't call parse_and_execute, free the
|
||||
temporary string, since parse_and_execute won't. Report and fix from
|
||||
Eric Kobrin <ekobrin@akamai.com>
|
||||
|
||||
10/4
|
||||
----
|
||||
print_cmd.c
|
||||
- print_function_def: when in posix mode, print shell function
|
||||
definitions as posix specifies them, without the leading
|
||||
`function' keyword
|
||||
|
||||
@@ -938,6 +938,11 @@ tests/exp3.sub f
|
||||
tests/exp4.sub f
|
||||
tests/exp5.sub f
|
||||
tests/exp6.sub f
|
||||
tests/exportfunc.tests f
|
||||
tests/exportfunc.right f
|
||||
tests/exportfunc1.sub f
|
||||
tests/exportfunc2.sub f
|
||||
tests/exportfunc3.sub f
|
||||
tests/extglob.tests f
|
||||
tests/extglob.right f
|
||||
tests/extglob1.sub f
|
||||
@@ -1131,6 +1136,7 @@ tests/run-dollars f
|
||||
tests/run-errors f
|
||||
tests/run-execscript f
|
||||
tests/run-exp-tests f
|
||||
tests/run-exportfunc f
|
||||
tests/run-extglob f
|
||||
tests/run-extglob2 f
|
||||
tests/run-extglob3 f
|
||||
|
||||
+22
-6
@@ -312,12 +312,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);
|
||||
@@ -382,7 +395,10 @@ parse_and_execute (string, from_file, flags)
|
||||
discard_unwind_frame ("pe_dispose");
|
||||
|
||||
if (flags & SEVAL_ONECMD)
|
||||
break;
|
||||
{
|
||||
reset_parser ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -188,6 +188,11 @@ set_or_show_attributes (list, attribute, nodefs)
|
||||
builtin_error (_("%s: not a function"), name);
|
||||
any_failed++;
|
||||
}
|
||||
else if ((attribute & att_exported) && undo == 0 && exportable_function_name (name) == 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot export"), name);
|
||||
any_failed++;
|
||||
}
|
||||
else
|
||||
SETVARATTR (var, attribute, undo);
|
||||
|
||||
|
||||
@@ -0,0 +1,560 @@
|
||||
This file is setattr.def, from which is created setattr.c.
|
||||
It implements the builtins "export" and "readonly", in Bash.
|
||||
|
||||
Copyright (C) 1987-2012 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES setattr.c
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../flags.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int array_needs_making;
|
||||
extern char *this_command_name;
|
||||
extern sh_builtin_func_t *this_shell_builtin;
|
||||
|
||||
#ifdef ARRAY_VARS
|
||||
extern int declare_builtin __P((WORD_LIST *));
|
||||
#endif
|
||||
|
||||
#define READONLY_OR_EXPORT \
|
||||
(this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
|
||||
|
||||
$BUILTIN export
|
||||
$FUNCTION export_builtin
|
||||
$SHORT_DOC export [-fn] [name[=value] ...] or export -p
|
||||
Set export attribute for shell variables.
|
||||
|
||||
Marks each NAME for automatic export to the environment of subsequently
|
||||
executed commands. If VALUE is supplied, assign VALUE before exporting.
|
||||
|
||||
Options:
|
||||
-f refer to shell functions
|
||||
-n remove the export property from each NAME
|
||||
-p display a list of all exported variables and functions
|
||||
|
||||
An argument of `--' disables further option processing.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is given or NAME is invalid.
|
||||
$END
|
||||
|
||||
/* For each variable name in LIST, make that variable appear in the
|
||||
environment passed to simple commands. If there is no LIST, then
|
||||
print all such variables. An argument of `-n' says to remove the
|
||||
exported attribute from variables named in LIST. An argument of
|
||||
-f indicates that the names present in LIST refer to functions. */
|
||||
int
|
||||
export_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
return (set_or_show_attributes (list, att_exported, 0));
|
||||
}
|
||||
|
||||
$BUILTIN readonly
|
||||
$FUNCTION readonly_builtin
|
||||
$SHORT_DOC readonly [-aAf] [name[=value] ...] or readonly -p
|
||||
Mark shell variables as unchangeable.
|
||||
|
||||
Mark each NAME as read-only; the values of these NAMEs may not be
|
||||
changed by subsequent assignment. If VALUE is supplied, assign VALUE
|
||||
before marking as read-only.
|
||||
|
||||
Options:
|
||||
-a refer to indexed array variables
|
||||
-A refer to associative array variables
|
||||
-f refer to shell functions
|
||||
-p display a list of all readonly variables or functions, depending on
|
||||
whether or not the -f option is given
|
||||
|
||||
An argument of `--' disables further option processing.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is given or NAME is invalid.
|
||||
$END
|
||||
|
||||
/* For each variable name in LIST, make that variable readonly. Given an
|
||||
empty LIST, print out all existing readonly variables. */
|
||||
int
|
||||
readonly_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
return (set_or_show_attributes (list, att_readonly, 0));
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
# define ATTROPTS "aAfnp"
|
||||
#else
|
||||
# define ATTROPTS "fnp"
|
||||
#endif
|
||||
|
||||
/* For each variable name in LIST, make that variable have the specified
|
||||
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
|
||||
remaining names in LIST (doesn't work for readonly). */
|
||||
int
|
||||
set_or_show_attributes (list, attribute, nodefs)
|
||||
register WORD_LIST *list;
|
||||
int attribute, nodefs;
|
||||
{
|
||||
register SHELL_VAR *var;
|
||||
int assign, undo, any_failed, assign_error, opt;
|
||||
int functions_only, arrays_only, assoc_only;
|
||||
int aflags;
|
||||
char *name;
|
||||
#if defined (ARRAY_VARS)
|
||||
WORD_LIST *nlist, *tlist;
|
||||
WORD_DESC *w;
|
||||
#endif
|
||||
|
||||
functions_only = arrays_only = assoc_only = 0;
|
||||
undo = any_failed = assign_error = 0;
|
||||
/* Read arguments from the front of the list. */
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, ATTROPTS)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'n':
|
||||
undo = 1;
|
||||
break;
|
||||
case 'f':
|
||||
functions_only = 1;
|
||||
break;
|
||||
#if defined (ARRAY_VARS)
|
||||
case 'a':
|
||||
arrays_only = 1;
|
||||
break;
|
||||
case 'A':
|
||||
assoc_only = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'p':
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
if (list)
|
||||
{
|
||||
if (attribute & att_exported)
|
||||
array_needs_making = 1;
|
||||
|
||||
/* Cannot undo readonly status, silently disallowed. */
|
||||
if (undo && (attribute & att_readonly))
|
||||
attribute &= ~att_readonly;
|
||||
|
||||
while (list)
|
||||
{
|
||||
name = list->word->word;
|
||||
|
||||
if (functions_only) /* xxx -f name */
|
||||
{
|
||||
var = find_function (name);
|
||||
if (var == 0)
|
||||
{
|
||||
builtin_error (_("%s: not a function"), name);
|
||||
any_failed++;
|
||||
}
|
||||
else if (exportable_function_name (name) == 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot export"), name);
|
||||
any_failed++;
|
||||
}
|
||||
else
|
||||
SETVARATTR (var, attribute, undo);
|
||||
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* xxx [-np] name[=value] */
|
||||
assign = assignment (name, 0);
|
||||
|
||||
aflags = 0;
|
||||
if (assign)
|
||||
{
|
||||
name[assign] = '\0';
|
||||
if (name[assign - 1] == '+')
|
||||
{
|
||||
aflags |= ASS_APPEND;
|
||||
name[assign - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (legal_identifier (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
if (assign)
|
||||
assign_error++;
|
||||
else
|
||||
any_failed++;
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assign) /* xxx [-np] name=value */
|
||||
{
|
||||
name[assign] = '=';
|
||||
if (aflags & ASS_APPEND)
|
||||
name[assign - 1] = '+';
|
||||
#if defined (ARRAY_VARS)
|
||||
/* Let's try something here. Turn readonly -a xxx=yyy into
|
||||
declare -ra xxx=yyy and see what that gets us. */
|
||||
if (arrays_only || assoc_only)
|
||||
{
|
||||
tlist = list->next;
|
||||
list->next = (WORD_LIST *)NULL;
|
||||
w = arrays_only ? make_word ("-ra") : make_word ("-rA");
|
||||
nlist = make_word_list (w, list);
|
||||
opt = declare_builtin (nlist);
|
||||
if (opt != EXECUTION_SUCCESS)
|
||||
assign_error++;
|
||||
list->next = tlist;
|
||||
dispose_word (w);
|
||||
free (nlist);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* This word has already been expanded once with command
|
||||
and parameter expansion. Call do_assignment_no_expand (),
|
||||
which does not do command or parameter substitution. If
|
||||
the assignment is not performed correctly, flag an error. */
|
||||
if (do_assignment_no_expand (name) == 0)
|
||||
assign_error++;
|
||||
name[assign] = '\0';
|
||||
if (aflags & ASS_APPEND)
|
||||
name[assign - 1] = '\0';
|
||||
}
|
||||
|
||||
set_var_attribute (name, attribute, undo);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SHELL_VAR **variable_list;
|
||||
register int i;
|
||||
|
||||
if ((attribute & att_function) || functions_only)
|
||||
{
|
||||
variable_list = all_shell_functions ();
|
||||
if (attribute != att_function)
|
||||
attribute &= ~att_function; /* so declare -xf works, for example */
|
||||
}
|
||||
else
|
||||
variable_list = all_shell_variables ();
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (attribute & att_array)
|
||||
{
|
||||
arrays_only++;
|
||||
if (attribute != att_array)
|
||||
attribute &= ~att_array;
|
||||
}
|
||||
else if (attribute & att_assoc)
|
||||
{
|
||||
assoc_only++;
|
||||
if (attribute != att_assoc)
|
||||
attribute &= ~att_assoc;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (variable_list)
|
||||
{
|
||||
for (i = 0; var = variable_list[i]; i++)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (arrays_only && array_p (var) == 0)
|
||||
continue;
|
||||
else if (assoc_only && assoc_p (var) == 0)
|
||||
continue;
|
||||
#endif
|
||||
if ((var->attributes & attribute))
|
||||
{
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
if (any_failed = sh_chkwrite (any_failed))
|
||||
break;
|
||||
}
|
||||
}
|
||||
free (variable_list);
|
||||
}
|
||||
}
|
||||
|
||||
return (assign_error ? EX_BADASSIGN
|
||||
: ((any_failed == 0) ? EXECUTION_SUCCESS
|
||||
: EXECUTION_FAILURE));
|
||||
}
|
||||
|
||||
/* Show all variable variables (v == 1) or functions (v == 0) with
|
||||
attributes. */
|
||||
int
|
||||
show_all_var_attributes (v, nodefs)
|
||||
int v, nodefs;
|
||||
{
|
||||
SHELL_VAR **variable_list, *var;
|
||||
int any_failed;
|
||||
register int i;
|
||||
|
||||
variable_list = v ? all_shell_variables () : all_shell_functions ();
|
||||
if (variable_list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
for (i = any_failed = 0; var = variable_list[i]; i++)
|
||||
{
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
if (any_failed = sh_chkwrite (any_failed))
|
||||
break;
|
||||
}
|
||||
free (variable_list);
|
||||
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
|
||||
don't show function definitions along with the name. If PATTR is
|
||||
non-zero, it indicates we're being called from `export' or `readonly'.
|
||||
In POSIX mode, this prints the name of the calling builtin (`export'
|
||||
or `readonly') instead of `declare', and doesn't print function defs
|
||||
when called by `export' or `readonly'. */
|
||||
int
|
||||
show_var_attributes (var, pattr, nodefs)
|
||||
SHELL_VAR *var;
|
||||
int pattr, nodefs;
|
||||
{
|
||||
char flags[16], *x;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
/* pattr == 0 means we are called from `declare'. */
|
||||
if (pattr == 0 || posixly_correct == 0)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (var))
|
||||
flags[i++] = 'a';
|
||||
|
||||
if (assoc_p (var))
|
||||
flags[i++] = 'A';
|
||||
#endif
|
||||
|
||||
if (function_p (var))
|
||||
flags[i++] = 'f';
|
||||
|
||||
if (integer_p (var))
|
||||
flags[i++] = 'i';
|
||||
|
||||
if (nameref_p (var))
|
||||
flags[i++] = 'n';
|
||||
|
||||
if (readonly_p (var))
|
||||
flags[i++] = 'r';
|
||||
|
||||
if (trace_p (var))
|
||||
flags[i++] = 't';
|
||||
|
||||
if (exported_p (var))
|
||||
flags[i++] = 'x';
|
||||
|
||||
if (capcase_p (var))
|
||||
flags[i++] = 'c';
|
||||
|
||||
if (lowercase_p (var))
|
||||
flags[i++] = 'l';
|
||||
|
||||
if (uppercase_p (var))
|
||||
flags[i++] = 'u';
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (var))
|
||||
flags[i++] = 'a';
|
||||
|
||||
if (assoc_p (var))
|
||||
flags[i++] = 'A';
|
||||
#endif
|
||||
|
||||
if (function_p (var))
|
||||
flags[i++] = 'f';
|
||||
}
|
||||
|
||||
flags[i] = '\0';
|
||||
|
||||
/* If we're printing functions with definitions, print the function def
|
||||
first, then the attributes, instead of printing output that can't be
|
||||
reused as input to recreate the current state. */
|
||||
if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
|
||||
{
|
||||
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
|
||||
nodefs++;
|
||||
if (pattr == 0 && i == 1 && flags[0] == 'f')
|
||||
return 0; /* don't print `declare -f name' */
|
||||
}
|
||||
|
||||
if (pattr == 0 || posixly_correct == 0)
|
||||
printf ("declare -%s ", i ? flags : "-");
|
||||
else if (i)
|
||||
printf ("%s -%s ", this_command_name, flags);
|
||||
else
|
||||
printf ("%s ", this_command_name);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (invisible_p (var) && (array_p (var) || assoc_p (var)))
|
||||
printf ("%s\n", var->name);
|
||||
else if (array_p (var))
|
||||
print_array_assignment (var, 1);
|
||||
else if (assoc_p (var))
|
||||
print_assoc_assignment (var, 1);
|
||||
else
|
||||
#endif
|
||||
/* force `readonly' and `export' to not print out function definitions
|
||||
when in POSIX mode. */
|
||||
if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
|
||||
printf ("%s\n", var->name);
|
||||
else if (function_p (var))
|
||||
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
|
||||
else if (invisible_p (var) || var_isset (var) == 0)
|
||||
printf ("%s\n", var->name);
|
||||
else
|
||||
{
|
||||
x = sh_double_quote (value_cell (var));
|
||||
printf ("%s=%s\n", var->name, x);
|
||||
free (x);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
show_name_attributes (name, nodefs)
|
||||
char *name;
|
||||
int nodefs;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
#if 0
|
||||
var = find_variable_tempenv (name);
|
||||
#else
|
||||
var = find_variable_noref (name);
|
||||
#endif
|
||||
|
||||
if (var /* && invisible_p (var) == 0 */) /* XXX bash-4.4/bash-5.0 */
|
||||
{
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
show_func_attributes (name, nodefs)
|
||||
char *name;
|
||||
int nodefs;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
var = find_function (name);
|
||||
|
||||
if (var)
|
||||
{
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
set_var_attribute (name, attribute, undo)
|
||||
char *name;
|
||||
int attribute, undo;
|
||||
{
|
||||
SHELL_VAR *var, *tv, *v;
|
||||
char *tvalue;
|
||||
|
||||
if (undo)
|
||||
var = find_variable (name);
|
||||
else
|
||||
{
|
||||
tv = find_tempenv_variable (name);
|
||||
/* XXX -- need to handle case where tv is a temp variable in a
|
||||
function-scope context, since function_env has been merged into
|
||||
the local variables table. */
|
||||
if (tv && tempvar_p (tv))
|
||||
{
|
||||
tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
|
||||
|
||||
var = bind_variable (tv->name, tvalue, 0);
|
||||
var->attributes |= tv->attributes & ~att_tempvar;
|
||||
/* This avoids an error message when propagating a read-only var
|
||||
later on. */
|
||||
if (var->context == 0 && (attribute & att_readonly))
|
||||
{
|
||||
/* Don't bother to set the `propagate to the global variables
|
||||
table' flag if we've just bound the variable in that table */
|
||||
v = find_global_variable (tv->name);
|
||||
if (v != var)
|
||||
VSETATTR (tv, att_propagate);
|
||||
}
|
||||
else
|
||||
VSETATTR (tv, att_propagate);
|
||||
if (var->context != 0)
|
||||
VSETATTR (var, att_propagate);
|
||||
SETVARATTR (tv, attribute, undo); /* XXX */
|
||||
|
||||
stupidly_hack_special_variables (tv->name);
|
||||
|
||||
free (tvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
var = find_variable_notempenv (name);
|
||||
if (var == 0)
|
||||
{
|
||||
var = bind_variable (name, (char *)NULL, 0);
|
||||
if (no_invisible_vars == 0)
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
else if (var->context != 0)
|
||||
VSETATTR (var, att_propagate);
|
||||
}
|
||||
}
|
||||
|
||||
if (var)
|
||||
SETVARATTR (var, attribute, undo);
|
||||
|
||||
if (var && (exported_p (var) || (attribute & att_exported)))
|
||||
array_needs_making++; /* XXX */
|
||||
}
|
||||
@@ -459,7 +459,7 @@ char **argv;
|
||||
void
|
||||
builtin_usage()
|
||||
{
|
||||
fprintf(stderr, "%s: usage: %s [-%s] [file ...]\n", prog, OPTIONS);
|
||||
fprintf(stderr, "%s: usage: %s [-%s] [file ...]\n", prog, prog, OPTIONS);
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
|
||||
@@ -245,15 +245,36 @@ check_identifier (word, check_word)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Return 1 if STRING is a function name that the shell will import from
|
||||
the environment. Currently we reject attempts to import shell functions
|
||||
containing slashes, beginning with newlines or containing blanks. In
|
||||
Posix mode, we require that STRING be a valid shell identifier. Not
|
||||
used yet. */
|
||||
int
|
||||
legal_function_name (string)
|
||||
importable_function_name (string, len)
|
||||
char *string;
|
||||
size_t len;
|
||||
{
|
||||
if (absolute_program (string)) /* don't allow slash */
|
||||
return 0;
|
||||
if (*string == '\n') /* can't start with a newline */
|
||||
return 0;
|
||||
if (shellblank (*string) || shellblank(string[len-1]))
|
||||
return 0;
|
||||
return (posixly_correct ? legal_identifier (string) : 1);
|
||||
}
|
||||
|
||||
int
|
||||
exportable_function_name (string)
|
||||
char *string;
|
||||
{
|
||||
if (absolute_program (string))
|
||||
return 0;
|
||||
if (mbschr (string, '=') != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 1 if STRING comprises a valid alias name. The shell accepts
|
||||
essentially all characters except those which must be quoted to the
|
||||
parser (which disqualifies them from alias expansion anyway) and `/'. */
|
||||
|
||||
+23
-1
@@ -53,6 +53,7 @@ extern int interactive_comments;
|
||||
extern int check_hashed_filenames;
|
||||
extern int source_uses_path;
|
||||
extern int source_searches_cwd;
|
||||
extern int posixly_correct;
|
||||
|
||||
static char *bash_special_tilde_expansions __P((char *));
|
||||
static int unquoted_tilde_word __P((const char *));
|
||||
@@ -244,15 +245,36 @@ check_identifier (word, check_word)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Return 1 if STRING is a function name that the shell will import from
|
||||
the environment. Currently we reject attempts to import shell functions
|
||||
containing slashes, beginning with newlines or containing blanks. In
|
||||
Posix mode, we require that STRING be a valid shell identifier. Not
|
||||
used yet. */
|
||||
int
|
||||
legal_function_name (string)
|
||||
importable_function_name (string, len)
|
||||
char *string;
|
||||
size_t len;
|
||||
{
|
||||
if (absolute_program (string)) /* don't allow slash */
|
||||
return 0;
|
||||
if (*string == '\n') /* can't start with a newline */
|
||||
return 0;
|
||||
if (shellblank (*string) || shellblank(string[len-1]))
|
||||
return 0;
|
||||
return (posixly_correct ? legal_identifier (string) : 1);
|
||||
}
|
||||
|
||||
int
|
||||
exportable_function_name (string)
|
||||
char *string;
|
||||
{
|
||||
if (absolute_program (name))
|
||||
return 0;
|
||||
if (mbschr (string, '=') != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 1 if STRING comprises a valid alias name. The shell accepts
|
||||
essentially all characters except those which must be quoted to the
|
||||
parser (which disqualifies them from alias expansion anyway) and `/'. */
|
||||
|
||||
@@ -283,7 +283,8 @@ extern void print_rlimtype __P((RLIMTYPE, int));
|
||||
extern int all_digits __P((char *));
|
||||
extern int legal_number __P((const char *, intmax_t *));
|
||||
extern int legal_identifier __P((char *));
|
||||
extern int legal_function_name __P((char *));
|
||||
extern int importable_function_name __P((char *, size_t));
|
||||
extern int exportable_function_name __P((char *));
|
||||
extern int check_identifier __P((WORD_DESC *, int));
|
||||
extern int legal_alias_name __P((char *, int));
|
||||
extern int assignment __P((const char *, int));
|
||||
|
||||
@@ -283,6 +283,7 @@ extern void print_rlimtype __P((RLIMTYPE, int));
|
||||
extern int all_digits __P((char *));
|
||||
extern int legal_number __P((const char *, intmax_t *));
|
||||
extern int legal_identifier __P((char *));
|
||||
extern int importable_function_name __P((char *, size_t));
|
||||
extern int check_identifier __P((WORD_DESC *, int));
|
||||
extern int legal_alias_name __P((char *, int));
|
||||
extern int assignment __P((const char *, int));
|
||||
|
||||
@@ -772,6 +772,9 @@ bgp_prune ()
|
||||
{
|
||||
struct pidstat *ps;
|
||||
|
||||
if (bgpids.npid == 0 || bgpids.list == 0)
|
||||
return; /* just paranoia */
|
||||
|
||||
while (bgpids.npid > js.c_childmax)
|
||||
{
|
||||
ps = bgpids.list;
|
||||
|
||||
@@ -2538,6 +2538,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
|
||||
@@ -4034,6 +4044,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||
/*(*/
|
||||
parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
|
||||
shell_eof_token = ')';
|
||||
|
||||
parse_string (string, "command substitution", sflags, &ep);
|
||||
|
||||
shell_eof_token = orig_eof_token;
|
||||
@@ -4041,8 +4052,8 @@ xparse_dolparen (base, string, indp, flags)
|
||||
reset_parser ();
|
||||
/* reset_parser clears shell_input_line and associated variables */
|
||||
restore_input_line_state (&ls);
|
||||
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
|
||||
|
||||
+1
-1
@@ -25,6 +25,6 @@
|
||||
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||
looks for to find the patch level (for the sccs version string). */
|
||||
|
||||
#define PATCHLEVEL 25
|
||||
#define PATCHLEVEL 28
|
||||
|
||||
#endif /* _PATCHLEVEL_H_ */
|
||||
|
||||
+6
-1
@@ -51,6 +51,7 @@ extern int printf __P((const char *, ...)); /* Yuck. Double yuck. */
|
||||
#endif
|
||||
|
||||
extern int indirection_level;
|
||||
extern int posixly_correct;
|
||||
|
||||
static int indentation;
|
||||
static int indentation_amount = 4;
|
||||
@@ -1275,7 +1276,11 @@ print_function_def (func)
|
||||
REDIRECT *func_redirects;
|
||||
|
||||
func_redirects = NULL;
|
||||
cprintf ("function %s () \n", func->name->word);
|
||||
/* When in posix mode, print functions as posix specifies them. */
|
||||
if (posixly_correct == 0)
|
||||
cprintf ("function %s () \n", func->name->word);
|
||||
else
|
||||
cprintf ("%s () \n", func->name->word);
|
||||
add_unwind_protect (reset_locals, 0);
|
||||
|
||||
indent (indentation);
|
||||
|
||||
+1595
File diff suppressed because it is too large
Load Diff
@@ -180,6 +180,8 @@ typedef struct _sh_input_line_state_t {
|
||||
} sh_input_line_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 *));
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
exportfunc ok 1
|
||||
exportfunc ok 2
|
||||
./exportfunc.tests: line 24: cve7169-bad: No such file or directory
|
||||
./exportfunc.tests: eval: line 30: syntax error: unexpected end of file
|
||||
./exportfunc.tests: line 30: cve7169-bad2: No such file or directory
|
||||
./exportfunc1.sub: line 1: maximum here-document count exceeded
|
||||
/usr/local/build/bash/bash-current/bash: warning: here-document at line 0 delimited by end-of-file (wanted `a')
|
||||
./exportfunc.tests: line 51: HELLO_WORLD: No such file or directory
|
||||
eval ok
|
||||
./exportfunc3.sub: line 10: export: foo=bar: cannot export
|
||||
status: 1
|
||||
equals-1
|
||||
/usr/local/build/bash/bash-current/bash: foo=bar: command not found
|
||||
bad echo
|
||||
./exportfunc3.sub: line 23: export: /bin/echo: cannot export
|
||||
bar
|
||||
@@ -0,0 +1,71 @@
|
||||
# normal operation
|
||||
foo()
|
||||
{
|
||||
echo exportfunc ok 1
|
||||
}
|
||||
export -f foo
|
||||
${THIS_SH} -c foo
|
||||
unset -f foo
|
||||
foo-a ()
|
||||
{
|
||||
echo exportfunc ok 2
|
||||
}
|
||||
export -f foo-a
|
||||
${THIS_SH} -c 'foo-a'
|
||||
|
||||
# CVE-2014-6271
|
||||
|
||||
env -i BASH_FUNC_foo%%='() { echo cve6271 ok; } ; echo BAD' ${THIS_SH} -c foo 2>/dev/null
|
||||
|
||||
# CVE-2014-7169
|
||||
|
||||
rm -f cve7169-bad
|
||||
env -i BASH_FUNC_X%%='() { (a)=>\' ${THIS_SH} -c cve7169-bad 2>/dev/null
|
||||
: < cve7169-bad
|
||||
rm -f cve7169-bad
|
||||
|
||||
echo cve7169-bad2 > bar
|
||||
rm -f cve7169-bad2
|
||||
eval 'X() { (a)>\' ; . ./bar 2>/dev/null
|
||||
: < cve7169-bad2
|
||||
rm -f cve7169-bad2 bar
|
||||
|
||||
# CVE-2014-7186
|
||||
${THIS_SH} ./exportfunc1.sub
|
||||
|
||||
# CVE-2014-7187
|
||||
${THIS_SH} ./exportfunc2.sub
|
||||
|
||||
# CVE-2014-6277
|
||||
|
||||
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<0 0" ${THIS_SH} -c foo 2>/dev/null
|
||||
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<`perl -e '{print "A"x100000}'` 0" ${THIS_SH} -c foo 2>/dev/null
|
||||
${THIS_SH} -c "f(){ x(){ _;}; x(){ _;}<<a;}"
|
||||
|
||||
# CVE-2014-6278
|
||||
|
||||
env 'BASH_FUNC_FOO%%=() { 0;}>r[0${$(}0 {>"$(id >/dev/tty)"; }' ${THIS_SH} -c : 2>/dev/null
|
||||
|
||||
rm -f HELLO_WORLD
|
||||
env BASH_FUNC_FOO%%='() { 0;}>r[0${$(}0 {>HELLO_WORLD; }' ${THIS_SH} -c : 2>/dev/null
|
||||
: < HELLO_WORLD
|
||||
|
||||
env BASH_FUNC_x%%='() { _;}>_[$($())] { echo vuln;}' ${THIS_SH} -c : 2>/dev/null
|
||||
|
||||
env -i BASH_FUNC_x%%='() { _; } >_[${ $() }] { id; }' ${THIS_SH} -c : 2>/dev/null
|
||||
|
||||
env BASH_FUNC_x%%=$'() { _;}>_[$($())]\n{ echo vuln;}' ${THIS_SH} -c : 2>/dev/null
|
||||
eval 'x() { _;}>_[$($())] { echo vuln;}' 2>/dev/null
|
||||
|
||||
eval 'foo() { _; } >_[${ $() }] ;{ echo eval ok; }'
|
||||
|
||||
# other tests fixed in bash43-030 concerning function name transformation
|
||||
env $'BASH_FUNC_\nfoo%%=() { echo transform-1; }' ${THIS_SH} -c foo 2>/dev/null
|
||||
env $'BASH_FUNC_foo\n%%=() { echo transform-2; }' ${THIS_SH} -c foo 2>/dev/null
|
||||
env $'BASH_FUNC_ foo %%=() { echo transform-3; }' ${THIS_SH} -c foo 2>/dev/null
|
||||
|
||||
unset -f foo
|
||||
env $'BASH_FUNC_#badname%%'=$'() { :; }\nfoo () { echo transform-4; } ' ${THIS_SH} -c 'foo' 2>/dev/null
|
||||
|
||||
# tests of exported names
|
||||
${THIS_SH} ./exportfunc3.sub
|
||||
@@ -0,0 +1,68 @@
|
||||
# normal operation
|
||||
foo()
|
||||
{
|
||||
echo exportfunc ok 1
|
||||
}
|
||||
export -f foo
|
||||
${THIS_SH} -c foo
|
||||
unset -f foo
|
||||
foo-a ()
|
||||
{
|
||||
echo exportfunc ok 2
|
||||
}
|
||||
export -f foo-a
|
||||
${THIS_SH} -c 'foo-a'
|
||||
|
||||
# CVE-2014-6271
|
||||
|
||||
env -i BASH_FUNC_foo%%='() { echo cve6271 ok; } ; echo BAD' ${THIS_SH} -c foo 2>/dev/null
|
||||
|
||||
# CVE-2014-7169
|
||||
|
||||
rm -f cve7169-bad
|
||||
env -i BASH_FUNC_X%%='() { (a)=>\' ${THIS_SH} -c cve7169-bad 2>/dev/null
|
||||
: < cve7169-bad
|
||||
rm -f cve7169-bad
|
||||
|
||||
echo cve7169-bad2 > bar
|
||||
rm -f cve7169-bad2
|
||||
eval 'X() { (a)>\' ; . ./bar 2>/dev/null
|
||||
: < cve7169-bad2
|
||||
rm -f cve7169-bad2 bar
|
||||
|
||||
# CVE-2014-7186
|
||||
${THIS_SH} ./exportfunc1.sub
|
||||
|
||||
# CVE-2014-7187
|
||||
${THIS_SH} ./exportfunc2.sub
|
||||
|
||||
# CVE-2014-6277
|
||||
|
||||
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<0 0" ${THIS_SH} -c foo 2>/dev/null
|
||||
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<`perl -e '{print "A"x100000}'` 0" ${THIS_SH} -c foo 2>/dev/null
|
||||
${THIS_SH} -c "f(){ x(){ _;}; x(){ _;}<<a;}"
|
||||
|
||||
# CVE-2014-6278
|
||||
|
||||
env 'BASH_FUNC_FOO%%=() { 0;}>r[0${$(}0 {>"$(id >/dev/tty)"; }' ${THIS_SH} -c : 2>/dev/null
|
||||
|
||||
rm -f HELLO_WORLD
|
||||
env BASH_FUNC_FOO%%='() { 0;}>r[0${$(}0 {>HELLO_WORLD; }' ${THIS_SH} -c : 2>/dev/null
|
||||
: < HELLO_WORLD
|
||||
|
||||
env BASH_FUNC_x%%='() { _;}>_[$($())] { echo vuln;}' ${THIS_SH} -c : 2>/dev/null
|
||||
|
||||
env -i BASH_FUNC_x%%='() { _; } >_[${ $() }] { id; }' ${THIS_SH} -c : 2>/dev/null
|
||||
|
||||
env BASH_FUNC_x%%=$'() { _;}>_[$($())]\n{ echo vuln;}' ${THIS_SH} -c : 2>/dev/null
|
||||
eval 'x() { _;}>_[$($())] { echo vuln;}' 2>/dev/null
|
||||
|
||||
eval 'foo() { _; } >_[${ $() }] ;{ echo eval ok; }'
|
||||
|
||||
# other tests fixed in bash43-030 concerning function name transformation
|
||||
env $'BASH_FUNC_\nfoo%%=() { echo transform-1; }' ${THIS_SH} -c foo 2>/dev/null
|
||||
env $'BASH_FUNC_foo\n%%=() { echo transform-2; }' ${THIS_SH} -c foo 2>/dev/null
|
||||
env $'BASH_FUNC_ foo %%=() { echo transform-3; }' ${THIS_SH} -c foo 2>/dev/null
|
||||
|
||||
unset -f foo
|
||||
env $'BASH_FUNC_#badname%%'=$'() { :; }\nfoo () { echo transform-4; } ' ${THIS_SH} -c 'foo' 2>/dev/null
|
||||
@@ -0,0 +1,21 @@
|
||||
cat <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
EOF
|
||||
|
||||
echo after EOF
|
||||
@@ -0,0 +1,400 @@
|
||||
for x1 in ; do :
|
||||
for x2 in ; do :
|
||||
for x3 in ; do :
|
||||
for x4 in ; do :
|
||||
for x5 in ; do :
|
||||
for x6 in ; do :
|
||||
for x7 in ; do :
|
||||
for x8 in ; do :
|
||||
for x9 in ; do :
|
||||
for x10 in ; do :
|
||||
for x11 in ; do :
|
||||
for x12 in ; do :
|
||||
for x13 in ; do :
|
||||
for x14 in ; do :
|
||||
for x15 in ; do :
|
||||
for x16 in ; do :
|
||||
for x17 in ; do :
|
||||
for x18 in ; do :
|
||||
for x19 in ; do :
|
||||
for x20 in ; do :
|
||||
for x21 in ; do :
|
||||
for x22 in ; do :
|
||||
for x23 in ; do :
|
||||
for x24 in ; do :
|
||||
for x25 in ; do :
|
||||
for x26 in ; do :
|
||||
for x27 in ; do :
|
||||
for x28 in ; do :
|
||||
for x29 in ; do :
|
||||
for x30 in ; do :
|
||||
for x31 in ; do :
|
||||
for x32 in ; do :
|
||||
for x33 in ; do :
|
||||
for x34 in ; do :
|
||||
for x35 in ; do :
|
||||
for x36 in ; do :
|
||||
for x37 in ; do :
|
||||
for x38 in ; do :
|
||||
for x39 in ; do :
|
||||
for x40 in ; do :
|
||||
for x41 in ; do :
|
||||
for x42 in ; do :
|
||||
for x43 in ; do :
|
||||
for x44 in ; do :
|
||||
for x45 in ; do :
|
||||
for x46 in ; do :
|
||||
for x47 in ; do :
|
||||
for x48 in ; do :
|
||||
for x49 in ; do :
|
||||
for x50 in ; do :
|
||||
for x51 in ; do :
|
||||
for x52 in ; do :
|
||||
for x53 in ; do :
|
||||
for x54 in ; do :
|
||||
for x55 in ; do :
|
||||
for x56 in ; do :
|
||||
for x57 in ; do :
|
||||
for x58 in ; do :
|
||||
for x59 in ; do :
|
||||
for x60 in ; do :
|
||||
for x61 in ; do :
|
||||
for x62 in ; do :
|
||||
for x63 in ; do :
|
||||
for x64 in ; do :
|
||||
for x65 in ; do :
|
||||
for x66 in ; do :
|
||||
for x67 in ; do :
|
||||
for x68 in ; do :
|
||||
for x69 in ; do :
|
||||
for x70 in ; do :
|
||||
for x71 in ; do :
|
||||
for x72 in ; do :
|
||||
for x73 in ; do :
|
||||
for x74 in ; do :
|
||||
for x75 in ; do :
|
||||
for x76 in ; do :
|
||||
for x77 in ; do :
|
||||
for x78 in ; do :
|
||||
for x79 in ; do :
|
||||
for x80 in ; do :
|
||||
for x81 in ; do :
|
||||
for x82 in ; do :
|
||||
for x83 in ; do :
|
||||
for x84 in ; do :
|
||||
for x85 in ; do :
|
||||
for x86 in ; do :
|
||||
for x87 in ; do :
|
||||
for x88 in ; do :
|
||||
for x89 in ; do :
|
||||
for x90 in ; do :
|
||||
for x91 in ; do :
|
||||
for x92 in ; do :
|
||||
for x93 in ; do :
|
||||
for x94 in ; do :
|
||||
for x95 in ; do :
|
||||
for x96 in ; do :
|
||||
for x97 in ; do :
|
||||
for x98 in ; do :
|
||||
for x99 in ; do :
|
||||
for x100 in ; do :
|
||||
for x101 in ; do :
|
||||
for x102 in ; do :
|
||||
for x103 in ; do :
|
||||
for x104 in ; do :
|
||||
for x105 in ; do :
|
||||
for x106 in ; do :
|
||||
for x107 in ; do :
|
||||
for x108 in ; do :
|
||||
for x109 in ; do :
|
||||
for x110 in ; do :
|
||||
for x111 in ; do :
|
||||
for x112 in ; do :
|
||||
for x113 in ; do :
|
||||
for x114 in ; do :
|
||||
for x115 in ; do :
|
||||
for x116 in ; do :
|
||||
for x117 in ; do :
|
||||
for x118 in ; do :
|
||||
for x119 in ; do :
|
||||
for x120 in ; do :
|
||||
for x121 in ; do :
|
||||
for x122 in ; do :
|
||||
for x123 in ; do :
|
||||
for x124 in ; do :
|
||||
for x125 in ; do :
|
||||
for x126 in ; do :
|
||||
for x127 in ; do :
|
||||
for x128 in ; do :
|
||||
for x129 in ; do :
|
||||
for x130 in ; do :
|
||||
for x131 in ; do :
|
||||
for x132 in ; do :
|
||||
for x133 in ; do :
|
||||
for x134 in ; do :
|
||||
for x135 in ; do :
|
||||
for x136 in ; do :
|
||||
for x137 in ; do :
|
||||
for x138 in ; do :
|
||||
for x139 in ; do :
|
||||
for x140 in ; do :
|
||||
for x141 in ; do :
|
||||
for x142 in ; do :
|
||||
for x143 in ; do :
|
||||
for x144 in ; do :
|
||||
for x145 in ; do :
|
||||
for x146 in ; do :
|
||||
for x147 in ; do :
|
||||
for x148 in ; do :
|
||||
for x149 in ; do :
|
||||
for x150 in ; do :
|
||||
for x151 in ; do :
|
||||
for x152 in ; do :
|
||||
for x153 in ; do :
|
||||
for x154 in ; do :
|
||||
for x155 in ; do :
|
||||
for x156 in ; do :
|
||||
for x157 in ; do :
|
||||
for x158 in ; do :
|
||||
for x159 in ; do :
|
||||
for x160 in ; do :
|
||||
for x161 in ; do :
|
||||
for x162 in ; do :
|
||||
for x163 in ; do :
|
||||
for x164 in ; do :
|
||||
for x165 in ; do :
|
||||
for x166 in ; do :
|
||||
for x167 in ; do :
|
||||
for x168 in ; do :
|
||||
for x169 in ; do :
|
||||
for x170 in ; do :
|
||||
for x171 in ; do :
|
||||
for x172 in ; do :
|
||||
for x173 in ; do :
|
||||
for x174 in ; do :
|
||||
for x175 in ; do :
|
||||
for x176 in ; do :
|
||||
for x177 in ; do :
|
||||
for x178 in ; do :
|
||||
for x179 in ; do :
|
||||
for x180 in ; do :
|
||||
for x181 in ; do :
|
||||
for x182 in ; do :
|
||||
for x183 in ; do :
|
||||
for x184 in ; do :
|
||||
for x185 in ; do :
|
||||
for x186 in ; do :
|
||||
for x187 in ; do :
|
||||
for x188 in ; do :
|
||||
for x189 in ; do :
|
||||
for x190 in ; do :
|
||||
for x191 in ; do :
|
||||
for x192 in ; do :
|
||||
for x193 in ; do :
|
||||
for x194 in ; do :
|
||||
for x195 in ; do :
|
||||
for x196 in ; do :
|
||||
for x197 in ; do :
|
||||
for x198 in ; do :
|
||||
for x199 in ; do :
|
||||
for x200 in ; do :
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
@@ -0,0 +1,25 @@
|
||||
# test function names that cannot be exported
|
||||
|
||||
unset foo # remove from environment if necessary
|
||||
|
||||
function foo=bar
|
||||
{
|
||||
echo equals-1
|
||||
}
|
||||
|
||||
export -f 'foo=bar'
|
||||
echo status: $?
|
||||
|
||||
foo\=bar
|
||||
printenv | grep 'foo=bar'
|
||||
${THIS_SH} -c 'foo\=bar'
|
||||
|
||||
function /bin/echo
|
||||
{
|
||||
echo bad echo
|
||||
}
|
||||
|
||||
/bin/echo foo
|
||||
export -f '/bin/echo'
|
||||
|
||||
${THIS_SH} -c '/bin/echo bar'
|
||||
@@ -0,0 +1,2 @@
|
||||
${THIS_SH} ./exportfunc.tests > /tmp/xx 2>&1
|
||||
diff /tmp/xx exportfunc.right && rm -f /tmp/xx
|
||||
@@ -424,6 +424,7 @@ trap_handler (sig)
|
||||
SIGRETURN (0);
|
||||
}
|
||||
|
||||
itrace("trap_handler: received %d", sig);
|
||||
if ((sig >= NSIG) ||
|
||||
(trap_list[sig] == (char *)DEFAULT_SIG) ||
|
||||
(trap_list[sig] == (char *)IGNORE_SIG))
|
||||
@@ -857,7 +858,9 @@ run_exit_trap ()
|
||||
retval = trap_saved_exit_value;
|
||||
|
||||
running_trap = 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
array_dispose (ps);
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
+4
-2
@@ -380,10 +380,12 @@ initialize_shell_variables (env, privmode)
|
||||
memcpy (temp_string + namelen + 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. */
|
||||
environment in posix mode, though we still allow them to be defined as
|
||||
shell variables. */
|
||||
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);
|
||||
else
|
||||
free (temp_string); /* parse_and_execute does this */
|
||||
|
||||
if (temp_var = find_function (tname))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* version.c -- distribution and version numbers. */
|
||||
|
||||
/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -43,7 +43,7 @@ const char * const release_status = (char *)0;
|
||||
#endif
|
||||
const char * const sccs_version = SCCSVERSION;
|
||||
|
||||
const char * const bash_copyright = N_("Copyright (C) 2013 Free Software Foundation, Inc.");
|
||||
const char * const bash_copyright = N_("Copyright (C) 2014 Free Software Foundation, Inc.");
|
||||
const char * const bash_license = N_("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n");
|
||||
|
||||
/* If == 31, shell compatible with bash-3.1, == 32 with bash-3.2, and so on */
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* version.c -- distribution and version numbers. */
|
||||
|
||||
/* Copyright (C) 1989-2012 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -43,7 +43,7 @@ const char * const release_status = (char *)0;
|
||||
#endif
|
||||
const char * const sccs_version = SCCSVERSION;
|
||||
|
||||
const char * const bash_copyright = N_("Copyright (C) 2012 Free Software Foundation, Inc.");
|
||||
const char * const bash_copyright = N_("Copyright (C) 2014 Free Software Foundation, Inc.");
|
||||
const char * const bash_license = N_("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n");
|
||||
|
||||
/* If == 31, shell compatible with bash-3.1, == 32 with bash-3.2, and so on */
|
||||
|
||||
Reference in New Issue
Block a user