libtool-patches
[Top][All Lists]
Advanced

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

Re: out of memory crash when accessing broken .la files


From: Ralf Wildenhues
Subject: Re: out of memory crash when accessing broken .la files
Date: Wed, 15 Aug 2007 23:39:12 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

* Dirk Mueller wrote on Wed, Aug 15, 2007 at 10:51:54AM CEST:
> On Wednesday, 15. August 2007, Ralf Wildenhues wrote:
> 
> > Could you post such a corrupted .la file, preferably gzip'ed so that it
> > won't be harmed by mail transport?  How did it get corrupted BTW?
> 
> The initial report came from a customer. He faced a filesystem corruption 
> that 
> caused several .la files on his system to be filled with NUL bytes. 

OK.  At least it wasn't some broken tool, or breakage in a Libtool
version we may not be aware of.

> I wasn`t able to investigate with his system, but I was able to reproduce it 
> trivially by fuzzing a valid file. I`m attaching what I used for testing. 

Thanks.  One problem is that .la file are also sourced by the libtool
script, thus the shell running the script may do all sorts of weird
things with broken files, or even just files with long lines, and really
I don't think there is any sensitive way to deal with this from inside
the script, apart from writing a full robust parser.  Note also that the
parser in ltdl.c is not all that robust to slight changes in the
structure.  libltdl assumes they do not come from an untrustworthy
source.  So maybe it's better your customer found out about the
corruption before the libtool script had a chance to go berserk...
I hope he replaces the disk before doing further work.

Anyway, your change causes also a small efficiency gain, as a strlen
is avoided; however, if the line is exactly line_len-1 bytes long,
it calls realloc unnecessarily and also eats part of the next line;
also let's avoid reading uninitialized memory in case we've already
needed to realloc before.  I've applied the patches below to branch-1-5
and HEAD, respectively.

Cheers, and thanks,
Ralf

HEAD:
2007-08-15  Dirk Mueller  <address@hidden>  (tiny change)
            Ralf Wildenhues  <address@hidden>

        * libltdl/ltdl.c (parse_dotla_file): Avoid a strlen.  When
        reading .la files, cope with files that are not
        newline-terminated.

Index: libltdl/ltdl.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v
retrieving revision 1.255
diff -u -r1.255 ltdl.c
--- libltdl/ltdl.c      5 Aug 2007 11:06:14 -0000       1.255
+++ libltdl/ltdl.c      15 Aug 2007 21:29:31 -0000
@@ -1017,14 +1017,16 @@
 
   while (!feof (file))
     {
+      line[line_len-2] = '\0';
       if (!fgets (line, (int) line_len, file))
        {
          break;
        }
 
       /* Handle the case where we occasionally need to read a line
-        that is longer than the initial buffer size.  */
-      while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
+        that is longer than the initial buffer size.
+         Behave even if the file contains NUL bytes due to corruption. */
+      while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof 
(file))
        {
          line = REALLOC (char, line, line_len *2);
          if (!line)
@@ -1033,6 +1035,7 @@
              ++errors;
              goto cleanup;
            }
+         line[line_len * 2 - 2] = '\0';
          if (!fgets (&line[line_len -1], (int) line_len +1, file))
            {
              break;


branch-1-5:
2007-08-15  Dirk Mueller  <address@hidden>  (tiny change)
            Ralf Wildenhues  <address@hidden>

        * libltdl/ltdl.c (try_dlopen): Avoid a strlen.  When reading .la
        files, cope with files that are not newline-terminated.

Index: libltdl/ltdl.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v
retrieving revision 1.174.2.28
diff -u -r1.174.2.28 ltdl.c
--- libltdl/ltdl.c      29 Jan 2007 21:54:10 -0000      1.174.2.28
+++ libltdl/ltdl.c      15 Aug 2007 13:44:37 -0000
@@ -3249,16 +3249,19 @@
       /* read the .la file */
       while (!feof (file))
        {
+         line[line_len-2] = '\0';
          if (!fgets (line, (int) line_len, file))
            {
              break;
            }
 
          /* Handle the case where we occasionally need to read a line
-            that is longer than the initial buffer size.  */
-         while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
+            that is longer than the initial buffer size.
+            Behave even if the file contains NUL bytes due to corruption. */
+         while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof 
(file))
            {
              line = LT_DLREALLOC (char, line, line_len *2);
+             line[line_len*2 - 2] = '\0';
              if (!fgets (&line[line_len -1], (int) line_len +1, file))
                {
                  break;




reply via email to

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