Subject: Re: bug#6149: 24.0.50; shell buffer overflow when input longer than 4096 bytes

From: Stefan Monnier <[email-masked]>
Date: Mon, 31 May 2010 21:50:37 -0400

>>>>> "jidanni" == jidanni  <[email-masked]> writes:

> This is a serious bug in M-x shell. It is not a bash or dash bug. It is
> not a readline bug. It does not happen in xterm. It does not happen when
> using pipes or backticks to get the input. It only happens in M-x
> shell... when one gives lines longer than ~4096 characters.

> Actually it is not buffer overflow, but buffer truncation, with NO
> WARNING to the user. One day the wrong file will get removed via this
> mess.

> In GNU Emacs 24.0.50.1 (i486-pc-linux-gnu, GTK+ Version 2.20.0)
>  of 2010-05-01 on elegiac, modified by Debian
>  (emacs-snapshot package, version 1:20100501-1)

Thanks for this nice test case.
It appears it was a silly mistake (code placed in the wrong side of
a #if).  I've installed the patch below which should fix it,

        Stefan

=== modified file 'src/sysdep.c'
--- src/sysdep.c	2010-05-04 07:40:53 +0000
+++ src/sysdep.c	2010-06-01 01:40:00 +0000
@@ -537,15 +537,6 @@
   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
 #endif /* AIX */
 
-#else /* not HAVE_TERMIO */
-
-  s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
-		       | CBREAK | TANDEM);
-  s.main.sg_flags |= LPASS8;
-  s.main.sg_erase = 0377;
-  s.main.sg_kill = 0377;
-  s.lmode = LLITOUT | s.lmode;        /* Don't strip 8th bit */
-
   /* We used to enable ICANON (and set VEOF to 04), but this leads to
      problems where process.c wants to send EOFs every once in a while
      to force the output, which leads to weird effects when the
@@ -558,6 +549,15 @@
   s.main.c_cc[VMIN] = 1;
   s.main.c_cc[VTIME] = 0;
 
+#else /* not HAVE_TERMIO */
+
+  s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
+		       | CBREAK | TANDEM);
+  s.main.sg_flags |= LPASS8;
+  s.main.sg_erase = 0377;
+  s.main.sg_kill = 0377;
+  s.lmode = LLITOUT | s.lmode;        /* Don't strip 8th bit */
+
 #endif /* not HAVE_TERMIO */
 
   EMACS_SET_TTY (out, &s, 0);