07a490
			     BASH PATCH REPORT
07a490
			     =================
07a490
07a490
Bash-Release:	4.2
07a490
Patch-ID:	bash42-053
07a490
07a490
Bug-Reported-by:	Michal Zalewski <lcamtuf@coredump.cx>
07a490
Bug-Reference-ID:
07a490
Bug-Reference-URL:
07a490
07a490
Bug-Description:
07a490
07a490
A combination of nested command substitutions and function importing from
07a490
the environment can cause bash to execute code appearing in the environment
07a490
variable value following the function definition.
07a490
07a490
Patch (apply with `patch -p0'):
07a490
07a490
*** ../bash-4.2.52/builtins/evalstring.c	2014-09-16 19:35:45.000000000 -0400
07a490
--- builtins/evalstring.c	2014-10-04 15:00:26.000000000 -0400
07a490
***************
07a490
*** 262,271 ****
07a490
  	      struct fd_bitmap *bitmap;
07a490
  
07a490
! 	      if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
07a490
  		{
07a490
! 		  internal_warning ("%s: ignoring function definition attempt", from_file);
07a490
! 		  should_jump_to_top_level = 0;
07a490
! 		  last_result = last_command_exit_value = EX_BADUSAGE;
07a490
! 		  break;
07a490
  		}
07a490
  
07a490
--- 262,284 ----
07a490
  	      struct fd_bitmap *bitmap;
07a490
  
07a490
! 	      if (flags & SEVAL_FUNCDEF)
07a490
  		{
07a490
! 		  char *x;
07a490
! 
07a490
! 		  /* If the command parses to something other than a straight
07a490
! 		     function definition, or if we have not consumed the entire
07a490
! 		     string, or if the parser has transformed the function
07a490
! 		     name (as parsing will if it begins or ends with shell
07a490
! 		     whitespace, for example), reject the attempt */
07a490
! 		  if (command->type != cm_function_def ||
07a490
! 		      ((x = parser_remaining_input ()) && *x) ||
07a490
! 		      (STREQ (from_file, command->value.Function_def->name->word) == 0))
07a490
! 		    {
07a490
! 		      internal_warning (_("%s: ignoring function definition attempt"), from_file);
07a490
! 		      should_jump_to_top_level = 0;
07a490
! 		      last_result = last_command_exit_value = EX_BADUSAGE;
07a490
! 		      reset_parser ();
07a490
! 		      break;
07a490
! 		    }
07a490
  		}
07a490
  
07a490
***************
07a490
*** 332,336 ****
07a490
  
07a490
  	      if (flags & SEVAL_ONECMD)
07a490
! 		break;
07a490
  	    }
07a490
  	}
07a490
--- 345,352 ----
07a490
  
07a490
  	      if (flags & SEVAL_ONECMD)
07a490
! 		{
07a490
! 		  reset_parser ();
07a490
! 		  break;
07a490
! 		}
07a490
  	    }
07a490
  	}
07a490
*** ../bash-4.2.52/parse.y	2014-09-30 19:24:19.000000000 -0400
07a490
--- parse.y	2014-10-04 15:00:26.000000000 -0400
07a490
***************
07a490
*** 2436,2439 ****
07a490
--- 2436,2449 ----
07a490
  }
07a490
  
07a490
+ char *
07a490
+ parser_remaining_input ()
07a490
+ {
07a490
+   if (shell_input_line == 0)
07a490
+     return 0;
07a490
+   if (shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len)
07a490
+     return '\0';	/* XXX */
07a490
+   return (shell_input_line + shell_input_line_index);
07a490
+ }
07a490
+ 
07a490
  #ifdef INCLUDE_UNUSED
07a490
  /* Back the input pointer up by one, effectively `ungetting' a character. */
07a490
***************
07a490
*** 3891,3896 ****
07a490
    /* reset_parser clears shell_input_line and associated variables */
07a490
    restore_input_line_state (&ls);
07a490
!   if (interactive)
07a490
!     token_to_read = 0;
07a490
  
07a490
    /* Need to find how many characters parse_and_execute consumed, update
07a490
--- 3901,3906 ----
07a490
    /* reset_parser clears shell_input_line and associated variables */
07a490
    restore_input_line_state (&ls);
07a490
! 
07a490
!   token_to_read = 0;
07a490
  
07a490
    /* Need to find how many characters parse_and_execute consumed, update
07a490
*** ../bash-4.2.52/shell.h	2011-11-21 18:03:32.000000000 -0500
07a490
--- shell.h	2014-10-04 15:00:26.000000000 -0400
07a490
***************
07a490
*** 178,181 ****
07a490
--- 178,183 ----
07a490
  
07a490
  /* Let's try declaring these here. */
07a490
+ extern char *parser_remaining_input __P((void));
07a490
+ 
07a490
  extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
07a490
  extern void restore_parser_state __P((sh_parser_state_t *));