emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Buffer overflow in term_init on FreeBSD 4-STABLE


From: Gerd Moellmann
Subject: Buffer overflow in term_init on FreeBSD 4-STABLE
Date: Sat, 16 Aug 2003 14:55:08 +0200 (CEST)

In GNU Emacs 21.3.50.6 (i386-unknown-freebsd4.8, X toolkit, Xaw3d scroll bars)
 of 2003-08-11

Emacs dumps core in term_init on FreeBSD 4-STABLE because of a buffer
overflow; tgetent returns an entry that is ca. 2800 bytes long, while
the buffer passed to tgetent is 2044 bytes long.

Environment variable "DISPLAY" not defined.
TERM = cons30
(gdb) b term_init
(gdb) r
Breakpoint 3, term_init (terminal_type=0xbfbffaf9 "console-30-iso8859-15")
    at term.c:2161
2161      char **address = &area;
2165      struct frame *sf = XFRAME (selected_frame);
2203      Wcm_clear ();
2205      status = tgetent (buffer, terminal_type);
2206      if (status < 0)
2214      if (status == 0)
2233      area = (char *) xmalloc (2044);
2237      if (area == 0)
2240      TS_ins_line = tgetstr ("al", address);
2241      TS_ins_multi_lines = tgetstr ("AL", address);
(gdb) p strlen(buffer)
$1 = 2811

This change in term.c makes it work.  Looking at FreeBSD sources, it
seems the limit is 4096.

Index: term.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/term.c,v
retrieving revision 1.146
diff -u -u -r1.146 term.c
--- term.c      24 May 2003 22:04:48 -0000      1.146
+++ term.c      16 Aug 2003 12:47:26 -0000
@@ -2159,7 +2159,8 @@
 {
   char *area;
   char **address = &area;
-  char buffer[2044];
+  char *buffer = NULL;
+  const int buffer_size = 4096;
   register char *p;
   int status;
   struct frame *sf = XFRAME (selected_frame);
@@ -2171,9 +2172,6 @@
 
   area = (char *) xmalloc (2044);
 
-  if (area == 0)
-    abort ();
-
   FrameRows = FRAME_LINES (sf);
   FrameCols = FRAME_COLS (sf);
   specified_window = FRAME_LINES (sf);
@@ -2202,6 +2200,7 @@
 
   Wcm_clear ();
 
+  buffer = (char *) xmalloc (buffer_size);
   status = tgetent (buffer, terminal_type);
   if (status < 0)
     {
@@ -2229,13 +2228,11 @@
             terminal_type);
 #endif
     }
-#ifdef TERMINFO
-  area = (char *) xmalloc (2044);
-#else
-  area = (char *) xmalloc (strlen (buffer));
-#endif /* not TERMINFO */
-  if (area == 0)
+
+  if (strlen (buffer) >= buffer_size)
     abort ();
+  
+  area = (char *) xmalloc (strlen (buffer));
 
   TS_ins_line = tgetstr ("al", address);
   TS_ins_multi_lines = tgetstr ("AL", address);
@@ -2560,6 +2557,8 @@
   FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
 #endif /* WINDOWSNT */
+
+  xfree (buffer);
 }
 
 /* VARARGS 1 */


We can also use TERMINFO on FreeBSD (doesn't have an effect on 
the length of what is returned by tgetent.)

Index: freebsd.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/s/freebsd.h,v
retrieving revision 1.39
diff -u -u -r1.39 freebsd.h
--- freebsd.h   4 Feb 2003 14:03:18 -0000       1.39
+++ freebsd.h   16 Aug 2003 12:48:08 -0000
@@ -68,6 +68,9 @@
 #define LIBS_SYSTEM -lutil
 #if __FreeBSD_version < 400000
 #define LIBS_TERMCAP -ltermcap
+#else
+#define TERMINFO
+#define LIBS_TERMCAP -lncurses
 #endif
 
 #define SYSV_SYSTEM_DIR




reply via email to

[Prev in Thread] Current Thread [Next in Thread]