emacs-devel
[Top][All Lists]
Advanced

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

[PATCH] make-docfile: don't corrupt heap for an invalid .elc file


From: Jim Meyering
Subject: [PATCH] make-docfile: don't corrupt heap for an invalid .elc file
Date: Wed, 26 Jan 2011 07:23:09 +0100

Felt like I should contribute more than rhetoric,
so poked around until I found this buffer underrun:

>From e99a6a402323a25038032e43114c00bc20a867e2 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 25 Jan 2011 21:47:10 +0100
Subject: [PATCH] make-docfile: don't corrupt heap for an invalid .elc file

"printf 'address@hidden' > in.elc; ./make-docfile in.elc" would write a '\0'
one byte before the just-malloc'd saved_string buffer.
* make-docfile.c (scan_lisp_file): Diagnose an invalid dynamic
doc string length.  Also fix an always-false while-loop test.
---
 lib-src/ChangeLog      |    8 ++++++++
 lib-src/make-docfile.c |   12 +++++++++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 2672791..e1dd3bf 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,11 @@
+2011-01-25  Jim Meyering  <address@hidden>
+
+       make-docfile: don't corrupt heap for an invalid .elc file
+       "printf 'address@hidden' > in.elc; ./make-docfile in.elc" would write a 
'\0'
+       one byte before the just-malloc'd saved_string buffer.
+       * make-docfile.c (scan_lisp_file): Diagnose an invalid dynamic
+       doc string length.  Also fix an always-false while-loop test.
+
 2011-01-25  Chong Yidong  <address@hidden>

        * movemail.c (main): Use setregid instead of setegid, which is
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index 0872f97..8addbda 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -873,8 +873,8 @@ scan_lisp_file (const char *filename, const char *mode)
          c = getc (infile);
          if (c == '@')
            {
-             int length = 0;
-             int i;
+             size_t length = 0;
+             size_t i;

              /* Read the length.  */
              while ((c = getc (infile),
@@ -884,6 +884,12 @@ scan_lisp_file (const char *filename, const char *mode)
                  length += c - '0';
                }

+             if (length <= 1)
+               fatal ("invalid dynamic doc string length", "");
+
+             if (c != ' ')
+               fatal ("space not found after dynamic doc string length", "");
+
              /* The next character is a space that is counted in the length
                 but not part of the doc string.
                 We already read it, so just ignore it.  */
@@ -899,7 +905,7 @@ scan_lisp_file (const char *filename, const char *mode)
                 but it is redundant in DOC.  So get rid of it here.  */
              saved_string[length - 1] = 0;
              /* Skip the line break.  */
-             while (c == '\n' && c == '\r')
+             while (c == '\n' || c == '\r')
                c = getc (infile);
              /* Skip the following line.  */
              while (c != '\n' && c != '\r')
--
1.7.3.5.38.gb312b



reply via email to

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