Workarounded cabextract memory leaks by captive memory tracker object. captive
authorshort <>
Thu, 11 Dec 2003 20:50:00 +0000 (20:50 +0000)
committershort <>
Thu, 11 Dec 2003 20:50:00 +0000 (20:50 +0000)
Fixed SIGSEGV-possible cabextract 'decomp_state' reentrancy.

src/install/acquire/cabextract/cabextract.c

index f5220df..d83803f 100644 (file)
@@ -154,6 +154,7 @@ extern time_t mktime(struct tm *tp);
 #include <glib/gmessages.h>
 #include <ctype.h>
 #include "../cabinet.h"
+#include "../cabinet-memory.h"
 #include "cabextract.h"
 
 #ifdef DEBUG
@@ -358,10 +359,11 @@ struct LZXstate {
 
 
 /* generic stuff */
-#define CAB(x) (decomp_state.x)
-#define ZIP(x) (decomp_state.methods.zip.x)
-#define QTM(x) (decomp_state.methods.qtm.x)
-#define LZX(x) (decomp_state.methods.lzx.x)
+#define decomp_state_ptr ((struct decomp_state *)acquire_cabinet_memory_data_get(sizeof(struct decomp_state)))
+#define CAB(x) (decomp_state_ptr->x)
+#define ZIP(x) (decomp_state_ptr->methods.zip.x)
+#define QTM(x) (decomp_state_ptr->methods.qtm.x)
+#define LZX(x) (decomp_state_ptr->methods.lzx.x)
 #define DECR_OK           (0)
 #define DECR_DATAFORMAT   (1)
 #define DECR_ILLEGALDATA  (2)
@@ -378,7 +380,7 @@ struct LZXstate {
 #define CAB_BLOCKMAX (32768)
 #define CAB_INPUTMAX (CAB_BLOCKMAX+6144)
 
-static struct {
+struct decomp_state {
   struct folder *current; /* current folder we're extracting from  */
   ULONG offset;           /* uncompressed offset within folder     */
   UBYTE *outpos;          /* (high level) start of data to use up  */
@@ -392,7 +394,7 @@ static struct {
     struct QTMstate qtm;
     struct LZXstate lzx;
   } methods;
-} decomp_state;
+};
 
 
 /* MSZIP decruncher */
@@ -434,7 +436,7 @@ static void Ziphuft_free(struct Ziphuft *t)
   while (p != (struct Ziphuft *)NULL)
   {
     q = (--p)->v.t;
-    free(p);
+    acquire_cabinet_memory_free(p);
     p = q;
   } 
 }
@@ -556,7 +558,7 @@ struct Ziphuft **t, LONG *m)
         l[h] = j;               /* set table size in stack */
 
         /* allocate and link in new table */
-        if (!(q = (struct Ziphuft *) malloc((z + 1)*sizeof(struct Ziphuft))))
+        if (!(q = (struct Ziphuft *) acquire_cabinet_memory_malloc((z + 1)*sizeof(struct Ziphuft))))
         {
           if(h)
             Ziphuft_free(ZIP(u)[0]);
@@ -1000,11 +1002,11 @@ static int QTMinit(int window, int level) {
   /* if a previously allocated window is big enough, keep it    */
   if (window < 10 || window > 21) return DECR_DATAFORMAT;
   if (QTM(actual_size) < (ULONG)wndsize) {
-    if (QTM(window)) free(QTM(window));
+    if (QTM(window)) acquire_cabinet_memory_free(QTM(window));
     QTM(window) = NULL;
   }
   if (!QTM(window)) {
-    if (!(QTM(window) = malloc(wndsize))) return DECR_NOMEMORY;
+    if (!(QTM(window) = acquire_cabinet_memory_malloc(wndsize))) return DECR_NOMEMORY;
     QTM(actual_size) = wndsize;
   }
   QTM(window_size) = wndsize;
@@ -1368,11 +1370,11 @@ static int LZXinit(int window) {
   /* if a previously allocated window is big enough, keep it     */
   if (window < 15 || window > 21) return DECR_DATAFORMAT;
   if (LZX(actual_size) < wndsize) {
-    if (LZX(window)) free(LZX(window));
+    if (LZX(window)) acquire_cabinet_memory_free(LZX(window));
     LZX(window) = NULL;
   }
   if (!LZX(window)) {
-    if (!(LZX(window) = malloc(wndsize))) return DECR_NOMEMORY;
+    if (!(LZX(window) = acquire_cabinet_memory_malloc(wndsize))) return DECR_NOMEMORY;
     LZX(actual_size) = wndsize;
   }
   LZX(window_size) = wndsize;
@@ -1988,7 +1990,7 @@ int file_open(struct file *fi, int lower, char *dir) {
   char c, *s, *d, *name;
   int ok = 0;
 
-  if (!(name = malloc(strlen(fi->filename) + (dir ? strlen(dir) : 0) + 2))) {
+  if (!(name = acquire_cabinet_memory_malloc(strlen(fi->filename) + (dir ? strlen(dir) : 0) + 2))) {
     g_warning(_("out of memory!"));
     return 0;
   }
@@ -2024,7 +2026,7 @@ int file_open(struct file *fi, int lower, char *dir) {
   }
 
   /* as full filename is no longer needed, free it */
-  free(name);
+  acquire_cabinet_memory_free(name);
 
   if (!ok) {
     perror(fi->filename);
@@ -2152,7 +2154,7 @@ static char *cabinet_read_string(struct cabinet *cab) {
   UBYTE *buf = NULL;
   do {
     if (len > maxlen) len = maxlen;
-    if (!(buf = realloc(buf, (size_t) len))) break;
+    if (!(buf = acquire_cabinet_memory_realloc(buf, (size_t) len))) break;
     if (!cabinet_read(cab, buf, (size_t) len)) break;
 
     /* search for a null terminator in what we've just read */
@@ -2171,7 +2173,7 @@ static char *cabinet_read_string(struct cabinet *cab) {
   } while (!ok);
 
   if (!ok) {
-    if (buf) free(buf); else g_warning(_("out of memory!"));
+    if (buf) acquire_cabinet_memory_free(buf); else g_warning(_("out of memory!"));
     return NULL;
   }
 
@@ -2258,7 +2260,7 @@ static int cabinet_read_entries(struct cabinet *cab) {
     if (!cabinet_read(cab, buf, cffold_SIZEOF)) return 0;
     if (folder_resv) cabinet_skip(cab, folder_resv);
 
-    fol = (struct folder *) calloc(1, sizeof(struct folder));
+    fol = (struct folder *) acquire_cabinet_memory_malloc0(sizeof(struct folder));
     if (!fol) { g_warning(_("out of memory!")); return 0; }
 
     fol->cab[0]     = cab;
@@ -2273,7 +2275,7 @@ static int cabinet_read_entries(struct cabinet *cab) {
   /* read files */
   for (i = 0; i < num_files; i++) {
     if (!cabinet_read(cab, buf, cffile_SIZEOF)) return 0;
-    file = (struct file *) calloc(1, sizeof(struct file));
+    file = (struct file *) acquire_cabinet_memory_malloc0(sizeof(struct file));
     if (!file) { g_warning(_("out of memory!")); return 0; }
       
     file->length   = EndGetI32(buf+cffile_UncompressedSize);
@@ -2384,7 +2386,7 @@ struct file *process_files(struct cabinet *basecab) {
  * otherwise.
  */
 static struct cabinet *load_cab_offset(struct acquire_cabinet *acquire_cabinet, off_t offset) {
-  struct cabinet *cab = (struct cabinet *) calloc(1, sizeof(struct cabinet));
+  struct cabinet *cab = (struct cabinet *) acquire_cabinet_memory_malloc0(sizeof(struct cabinet));
   int ok;
   if (!cab) return NULL;
 
@@ -2397,7 +2399,7 @@ static struct cabinet *load_cab_offset(struct acquire_cabinet *acquire_cabinet,
   /* cabinet_close(cab); * CAPTIVE */
 
   if (ok) return cab;
-  free(cab);
+  acquire_cabinet_memory_free(cab);
   return NULL;
 }
 
@@ -2419,7 +2421,7 @@ struct cabinet *find_cabs_in_file(struct acquire_cabinet *acquire_cabinet) {
   int state = 0, found = 0, ok = 0;
 
   /* open the file and search for cabinet headers */
-  if ((cab = (struct cabinet *) calloc(1, sizeof(struct cabinet)))) {
+  if ((cab = (struct cabinet *) acquire_cabinet_memory_malloc0(sizeof(struct cabinet)))) {
     cab->acquire_cabinet = acquire_cabinet;
     cab->filename = acquire_cabinet->filename;
     cab->filelen = acquire_cabinet->size;
@@ -2508,7 +2510,7 @@ struct cabinet *find_cabs_in_file(struct acquire_cabinet *acquire_cabinet) {
       }
       /* cabinet_close(cab); * CAPTIVE */
     }
-    free(cab);
+    acquire_cabinet_memory_free(cab);
   }
 
   /* if there were cabinets that were found but are not ok, point this out */
@@ -2574,7 +2576,7 @@ void print_fileinfo(struct file *fi) {
   char *fname = NULL;
 
   if (fi->attribs & cffile_A_NAME_IS_UTF) {
-    fname = malloc(strlen(fi->filename) + 1);
+    fname = acquire_cabinet_memory_malloc(strlen(fi->filename) + 1);
     if (fname) {
       strcpy(fname, fi->filename);
       convertUTF((UBYTE *) fname);
@@ -2588,7 +2590,7 @@ void print_fileinfo(struct file *fi) {
     fname ? fname : fi->filename
   );
 
-  if (fname) free(fname);
+  if (fname) acquire_cabinet_memory_free(fname);
 }
 
 #endif /* CAPTIVE */
@@ -2741,13 +2743,13 @@ int extract_file(struct file *fi, int lower, int fix, char *dir) {
       switch (ct2) {
       case cffoldCOMPTYPE_LZX:
         if (LZX(window)) {
-         free(LZX(window));
+         acquire_cabinet_memory_free(LZX(window));
          LZX(window) = NULL;
        }
        break;
       case cffoldCOMPTYPE_QUANTUM:
        if (QTM(window)) {
-         free(QTM(window));
+         acquire_cabinet_memory_free(QTM(window));
          QTM(window) = NULL;
        }
        break;
@@ -2858,7 +2860,7 @@ void find_cabinet_file(char **cabname, char *origcab) {
   /* find if there's a directory path in the origcab */
   tail = origcab ? strrchr(origcab, '/') : NULL;
 
-  if ((cab = (char *) malloc((tail ? tail-origcab : 1) + strlen(name) + 2))) {
+  if ((cab = (char *) acquire_cabinet_memory_malloc((tail ? tail-origcab : 1) + strlen(name) + 2))) {
     /* add the directory path from the original cabinet name */
     if (tail) {
       memcpy(cab, origcab, tail-origcab);
@@ -2913,11 +2915,11 @@ void find_cabinet_file(char **cabname, char *origcab) {
      * otherwise, pretend nothing happened
      */
     if (found) {
-      free((void *) *cabname);
+      acquire_cabinet_memory_free((void *) *cabname);
       *cabname = cab;
     }
     else {
-      free((void *) cab);
+      acquire_cabinet_memory_free((void *) cab);
     }
   }
 }