Author: ngie
Date: Sun Dec  6 21:07:33 2015
New Revision: 291908
URL: https://svnweb.freebsd.org/changeset/base/291908

Log:
  Fix leak in mkfs_msdos(..) by initializing img to NULL and free'ing at the end
  of the function
  
  Differential Revision: https://reviews.freebsd.org/D4405
  MFC after: 1 week
  PR: 204943
  Reviewed by: emaste, jilles
  Reported by: David Binderman <dcb...@hotmail.com>
  Sponsored by: EMC / Isilon Storage Division

Modified:
  head/sbin/newfs_msdos/mkfs_msdos.c

Modified: head/sbin/newfs_msdos/mkfs_msdos.c
==============================================================================
--- head/sbin/newfs_msdos/mkfs_msdos.c  Sun Dec  6 17:46:12 2015        
(r291907)
+++ head/sbin/newfs_msdos/mkfs_msdos.c  Sun Dec  6 21:07:33 2015        
(r291908)
@@ -242,38 +242,41 @@ mkfs_msdos(const char *fname, const char
     ssize_t n;
     time_t now;
     u_int fat, bss, rds, cls, dir, lsn, x, x1, x2;
-    int fd, fd1;
+    int fd, fd1, rv;
     struct msdos_options o = *op;
 
+    img = NULL;
+    rv = -1;
+
     if (o.block_size && o.sectors_per_cluster) {
        warnx("Cannot specify both block size and sectors per cluster");
-       return -1;
+       goto done;
     }
     if (o.OEM_string && strlen(o.OEM_string) > 8) {
        warnx("%s: bad OEM string", o.OEM_string);
-       return -1;
+       goto done;
     }
     if (o.create_size) {
        if (o.no_create) {
            warnx("create (-C) is incompatible with -N");
-           return -1;
+           goto done;
        }
        fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644);
        if (fd == -1) {
            warnx("failed to create %s", fname);
-           return -1;
+           goto done;
        }
        if (ftruncate(fd, o.create_size)) {
            warnx("failed to initialize %jd bytes", (intmax_t)o.create_size);
-           return -1;
+           goto done;
        }
     } else if ((fd = open(fname, o.no_create ? O_RDONLY : O_RDWR)) == -1) {
        warn("%s", fname);
-       return -1;
+       goto done;
     }
     if (fstat(fd, &sb)) {
        warn("%s", fname);
-       return -1;
+       goto done;
     }
     if (o.create_size) {
        if (!S_ISREG(sb.st_mode))
@@ -284,15 +287,15 @@ mkfs_msdos(const char *fname, const char
     }
     if (!o.no_create)
        if (check_mounted(fname, sb.st_mode) == -1)
-           return -1;
+           goto done;
     if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) {
        warnx("cannot seek to %jd", (intmax_t)o.offset);
-       return -1;
+       goto done;
     }
     memset(&bpb, 0, sizeof(bpb));
     if (o.floppy) {
        if (getstdfmt(o.floppy, &bpb) == -1)
-           return -1;
+           goto done;
        bpb.bpbHugeSectors = bpb.bpbSectors;
        bpb.bpbSectors = 0;
        bpb.bpbBigFATsecs = bpb.bpbFATsecs;
@@ -334,17 +337,17 @@ mkfs_msdos(const char *fname, const char
     }
     if (!powerof2(bpb.bpbBytesPerSec)) {
        warnx("bytes/sector (%u) is not a power of 2", bpb.bpbBytesPerSec);
-       return -1;
+       goto done;
     }
     if (bpb.bpbBytesPerSec < MINBPS) {
        warnx("bytes/sector (%u) is too small; minimum is %u",
             bpb.bpbBytesPerSec, MINBPS);
-       return -1;
+       goto done;
     }
 
     if (o.volume_label && !oklabel(o.volume_label)) {
        warnx("%s: bad volume label", o.volume_label);
-       return -1;
+       goto done;
     }
     if (!(fat = o.fat_type)) {
        if (o.floppy)
@@ -356,29 +359,29 @@ mkfs_msdos(const char *fname, const char
        warnx("-%c is not a legal FAT%s option",
             fat == 32 ? 'e' : o.info_sector ? 'i' : 'k',
             fat == 32 ? "32" : "12/16");
-       return -1;
+       goto done;
     }
     if (o.floppy && fat == 32)
        bpb.bpbRootDirEnts = 0;
     if (fat != 0 && fat != 12 && fat != 16 && fat != 32) {
        warnx("%d: bad FAT type", fat);
-       return -1;
+       goto done;
     }
 
     if (o.block_size) {
        if (!powerof2(o.block_size)) {
            warnx("block size (%u) is not a power of 2", o.block_size);
-           return -1;
+           goto done;
        }
        if (o.block_size < bpb.bpbBytesPerSec) {
            warnx("block size (%u) is too small; minimum is %u",
                 o.block_size, bpb.bpbBytesPerSec);
-           return -1;
+           goto done;
        }
        if (o.block_size > bpb.bpbBytesPerSec * MAXSPC) {
            warnx("block size (%u) is too large; maximum is %u",
                 o.block_size, bpb.bpbBytesPerSec * MAXSPC);
-           return -1;
+           goto done;
        }
        bpb.bpbSecPerClust = o.block_size / bpb.bpbBytesPerSec;
     }
@@ -386,7 +389,7 @@ mkfs_msdos(const char *fname, const char
        if (!powerof2(o.sectors_per_cluster)) {
            warnx("sectors/cluster (%u) is not a power of 2",
                o.sectors_per_cluster);
-           return -1;
+           goto done;
        }
        bpb.bpbSecPerClust = o.sectors_per_cluster;
     }
@@ -396,7 +399,7 @@ mkfs_msdos(const char *fname, const char
        if (o.num_FAT > MAXNFT) {
            warnx("number of FATs (%u) is too large; maximum is %u",
                 o.num_FAT, MAXNFT);
-           return -1;
+           goto done;
        }
        bpb.bpbFATs = o.num_FAT;
     }
@@ -405,7 +408,7 @@ mkfs_msdos(const char *fname, const char
     if (o.media_descriptor_set) {
        if (o.media_descriptor < 0xf0) {
            warnx("illegal media descriptor (%#x)", o.media_descriptor);
-           return -1;
+           goto done;
        }
        bpb.bpbMedia = o.media_descriptor;
     }
@@ -424,18 +427,18 @@ mkfs_msdos(const char *fname, const char
            snprintf(buf, sizeof(buf), "/boot/%s", bname);
            if (!(bname = strdup(buf))) {
                warn(NULL);
-               return -1;
+               goto done;
            }
        }
        if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb)) {
            warn("%s", bname);
-           return -1;
+           goto done;
        }
        if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bpbBytesPerSec ||
            sb.st_size < bpb.bpbBytesPerSec ||
            sb.st_size > bpb.bpbBytesPerSec * MAXU16) {
            warnx("%s: inappropriate file type or format", bname);
-           return -1;
+           goto done;
        }
        bss = sb.st_size / bpb.bpbBytesPerSec;
     }
@@ -470,7 +473,7 @@ mkfs_msdos(const char *fname, const char
        if (!bpb.bpbFSInfo) {
            if (x == MAXU16 || x == bpb.bpbBackup) {
                warnx("no room for info sector");
-               return -1;
+               goto done;
            }
            bpb.bpbFSInfo = x;
        }
@@ -479,12 +482,12 @@ mkfs_msdos(const char *fname, const char
        if (!bpb.bpbBackup) {
            if (x == MAXU16) {
                warnx("no room for backup sector");
-               return -1;
+               goto done;
            }
            bpb.bpbBackup = x;
        } else if (bpb.bpbBackup != MAXU16 && bpb.bpbBackup == bpb.bpbFSInfo) {
            warnx("backup sector would overwrite info sector");
-           return -1;
+           goto done;
        }
        if (bpb.bpbBackup != MAXU16 && x <= bpb.bpbBackup)
            x = bpb.bpbBackup + 1;
@@ -495,7 +498,7 @@ mkfs_msdos(const char *fname, const char
     else if (bpb.bpbResSectors < x) {
        warnx("too few reserved sectors (need %d have %d)", x,
             bpb.bpbResSectors);
-       return -1;
+       goto done;
     }
     if (fat != 32 && !bpb.bpbRootDirEnts)
        bpb.bpbRootDirEnts = DEFRDE;
@@ -515,13 +518,13 @@ mkfs_msdos(const char *fname, const char
            continue;
     if (fat != 32 && bpb.bpbBigFATsecs > MAXU16) {
        warnx("too many sectors/FAT for FAT12/16");
-       return -1;
+       goto done;
     }
     x1 = bpb.bpbResSectors + rds;
     x = bpb.bpbBigFATsecs ? bpb.bpbBigFATsecs : 1;
     if (x1 + (u_int64_t)x * bpb.bpbFATs > bpb.bpbHugeSectors) {
        warnx("meta data exceeds file system size");
-       return -1;
+       goto done;
     }
     x1 += x * bpb.bpbFATs;
     x = (u_int64_t)(bpb.bpbHugeSectors - x1) * bpb.bpbBytesPerSec * NPB /
@@ -544,7 +547,7 @@ mkfs_msdos(const char *fname, const char
     if (cls < mincls(fat)) {
        warnx("%u clusters too few clusters for FAT%u, need %u", cls, fat,
            mincls(fat));
-       return -1;
+       goto done;
     }
     if (cls > maxcls(fat)) {
        cls = maxcls(fat);
@@ -575,7 +578,7 @@ mkfs_msdos(const char *fname, const char
        tm = localtime(&now);
        if (!(img = malloc(bpb.bpbBytesPerSec))) {
            warn(NULL);
-           return -1;
+           goto done;
        }
        dir = bpb.bpbResSectors + (bpb.bpbFATsecs ? bpb.bpbFATsecs :
                                   bpb.bpbBigFATsecs) * bpb.bpbFATs;
@@ -583,7 +586,7 @@ mkfs_msdos(const char *fname, const char
        si_sa.sa_handler = infohandler;
        if (sigaction(SIGINFO, &si_sa, NULL) == -1) {
            warn("sigaction SIGINFO");
-           return -1;
+           goto done;
        }
        for (lsn = 0; lsn < dir + (fat == 32 ? bpb.bpbSecPerClust : rds); 
lsn++) {
            if (got_siginfo) {
@@ -601,17 +604,17 @@ mkfs_msdos(const char *fname, const char
                x -= bpb.bpbBackup;
                if (!x && lseek(fd1, o.offset, SEEK_SET)) {
                    warn("%s", bname);
-                   return -1;
+                   goto done;
                }
            }
            if (o.bootstrap && x < bss) {
                if ((n = read(fd1, img, bpb.bpbBytesPerSec)) == -1) {
                    warn("%s", bname);
-                   return -1;
+                   goto done;
                }
                if ((unsigned)n != bpb.bpbBytesPerSec) {
                    warnx("%s: can't read sector %u", bname, x);
-                   return -1;
+                   goto done;
                }
            } else
                memset(img, 0, bpb.bpbBytesPerSec);
@@ -701,15 +704,19 @@ mkfs_msdos(const char *fname, const char
            }
            if ((n = write(fd, img, bpb.bpbBytesPerSec)) == -1) {
                warn("%s", fname);
-               return -1;
+               goto done;
            }
            if ((unsigned)n != bpb.bpbBytesPerSec) {
                warnx("%s: can't write sector %u", fname, lsn);
-               return -1;
+               goto done;
            }
        }
     }
-    return 0;
+    rv = 0;
+done:
+    free(img);
+
+    return rv;
 }
 
 /*
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to