]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Fix xsparse.c big heap allocation bugs
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 6 Nov 2024 18:02:02 +0000 (10:02 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 6 Nov 2024 18:18:55 +0000 (10:18 -0800)
* scripts/xsparse.c (expand_sparse): Read into auto buffer, not heap.
The heap code was wrong for two reasons: it called malloc just once
in the try-again loop, and even when it succeeded it could have
left so few bytes available in the heap that later stdio calls
could fail.  Reading into the auto buffer might be a bit slower
but speed is not an issue here and it’s better to be simple.

scripts/xsparse.c

index 625b04d9dc680017000d7807fb266172d4d35201..8559d10593b4824c5ef30e7b9f2d8555dd98df64 100644 (file)
@@ -281,19 +281,6 @@ static void
 expand_sparse (FILE *sfp, int ofd)
 {
   size_t i;
-  off_t max_numbytes = 0;
-  size_t maxbytes;
-  char *buffer;
-
-  for (i = 0; i < sparse_map_size; i++)
-    if (max_numbytes < sparse_map[i].numbytes)
-      max_numbytes = sparse_map[i].numbytes;
-
-  maxbytes = max_numbytes < SIZE_MAX ? max_numbytes : SIZE_MAX;
-
-  for (buffer = malloc (maxbytes); !buffer; maxbytes /= 2)
-    if (maxbytes == 0)
-      die (1, "not enough memory");
 
   for (i = 0; i < sparse_map_size; i++)
     {
@@ -310,7 +297,8 @@ expand_sparse (FILE *sfp, int ofd)
            die (1, "lseek error (%d)", errno);
          while (size)
            {
-             size_t rdsize = (size < maxbytes) ? size : maxbytes;
+             char buffer[BUFSIZ];
+             size_t rdsize = size < BUFSIZ ? size : BUFSIZ;
              if (rdsize != fread (buffer, 1, rdsize, sfp))
                die (1, "read error (%d)", errno);
              if (0 <= ofd)
@@ -323,7 +311,6 @@ expand_sparse (FILE *sfp, int ofd)
            }
        }
     }
-  free (buffer);
 }
 
 static void