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