Martin Bialasinski wrote:
: 
: An attacker can create a directory name containing 0x03 0x014 followd
: by some command, and mc will execute this command, if someone enters
: this directory. mc 4.5.40 - 4.5.51 is affected.
: 
: I just tested this, and it does work :-(
: 
0x03 is an intr character on most *nix'es, but it can be changed by stty, etc.

Patch below is dirty hack, subshell still can't chdir to such directories,
but command is not executed.

Terminal programming is my weak area, so professional are welcomed.

P.S. Another ms's bug: when command line is more than 8KB long mc go sleep
forever in subshell.c:invoke_subshell ()

    else  /* MC has passed us a user command */
    {
        if (how == QUIETLY)
            write (subshell_pty, " ", 1);
// FIXME: If command is more than 8KB long, we get coma 
        write (subshell_pty, command, strlen (command));
        
        write (subshell_pty, "\n", 1);
        subshell_state = RUNNING_COMMAND;
        subshell_ready = FALSE;
    }
Index: subshell.c
===================================================================
RCS file: /cvs/gnome/mc/src/subshell.c,v
retrieving revision 1.19
diff -u -r1.19 subshell.c
--- subshell.c  2000/08/22 22:50:15     1.19
+++ subshell.c  2001/01/11 12:46:34
@@ -754,8 +754,6 @@
 /* If it actually changed the directory it returns true */
 void do_subshell_chdir (char *directory, int do_update, int reset_prompt)
 {
-    char *temp;
-    
     if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, cpanel->cwd))){
        /* We have to repaint the subshell prompt if we read it from
         * the main program.  Please note that in the code after this
@@ -770,9 +768,17 @@
        because we set "HISTCONTROL=ignorespace") */
     write (subshell_pty, " cd ", 4);
     if (*directory) {
-       temp = name_quote (directory, 0);
-       write (subshell_pty, temp, strlen (temp));    
-       g_free (temp);
+       struct termios old_mode, new_mode;
+       char *temp = name_quote (directory, 0);
+
+       tcgetattr (subshell_pty, &old_mode);
+       memcpy (&new_mode, &old_mode, sizeof (new_mode));
+       new_mode.c_lflag &= ~ISIG;    /* Disable intr, quit & suspend chars */
+       tcsetattr (subshell_pty, TCSANOW, &new_mode);
+
+       write (subshell_pty, temp, strlen (temp));
+       g_free (temp);
+       tcsetattr (subshell_pty, TCSANOW, &old_mode);
     } else {
        write (subshell_pty, "/", 1);
     }

Reply via email to