Hi,

this diff merges NetBSD's revision 1.20 into our tree:  There are
some memory leaks in resetDosDirSection.

This is not a simple merge, I have added some things:

- rootDir was not properly freed in NetBSD's commit
  (actually it's put into a "free dir entry queue")
- also free memory if root directory checks fail
- I use goto's instead of rewriting the code every single time
- kept our local styles (like xperror vs perr)
- after free, set values to NULL;  better safe than sorry and also
  in sync with other functions


Tobias

Index: dir.c
===================================================================
RCS file: /cvs/src/sbin/fsck_msdos/dir.c,v
retrieving revision 1.23
diff -u -p -r1.23 dir.c
--- dir.c       18 Jun 2014 17:29:07 -0000      1.23
+++ dir.c       30 Jun 2014 19:19:26 -0000
@@ -219,18 +219,27 @@ resetDosDirSection(struct bootblock *boo
        b1 = boot->RootDirEnts * 32;
        b2 = boot->SecPerClust * boot->BytesPerSec;
 
-       if (!(buffer = malloc(b1 > b2 ? b1 : b2))
-           || !(delbuf = malloc(b2))
-           || !(rootDir = newDosDirEntry())) {
+       if ((buffer = malloc(b1 > b2 ? b1 : b2)) == NULL) {
                xperror("No space for directory");
                return (FSFATAL);
        }
+
+       if ((delbuf = malloc(b2)) == NULL) {
+               xperror("No space for directory delbuf");
+               goto fail_delbuf;
+       }
+
+       if ((rootDir = newDosDirEntry()) == NULL) {
+               xperror("No space for directory entry");
+               goto fail_root;
+       }
+
        (void)memset(rootDir, 0, sizeof *rootDir);
        if (boot->flags & FAT32) {
                if (boot->RootCl < CLUST_FIRST || boot->RootCl >= 
boot->NumClusters) {
                        pfatal("Root directory starts with cluster out of 
range(%u)\n",
                               boot->RootCl);
-                       return (FSFATAL);
+                       goto fail;
                }
                cl = fat[boot->RootCl].next;
                if (cl < CLUST_FIRST
@@ -243,7 +252,7 @@ resetDosDirSection(struct bootblock *boo
                                      rsrvdcltype(cl));
                        else {
                                pfatal("Root directory doesn't start a cluster 
chain\n");
-                               return (FSFATAL);
+                               goto fail;
                        }
                        if (ask(1, "Fix")) {
                                fat[boot->RootCl].next = CLUST_FREE;
@@ -257,6 +266,16 @@ resetDosDirSection(struct bootblock *boo
        }
 
        return (ret);
+fail:
+       freeDosDirEntry(rootDir);
+       rootDir = NULL;
+fail_root:
+       free(delbuf);
+       delbuf = NULL;
+fail_delbuf:
+       free(buffer);
+       buffer = NULL;
+       return (FSFATAL);
 }
 
 /*

Reply via email to