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