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); } /*