Blame SOURCES/bash42-053

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