svn commit: r291908 - head/sbin/newfs_msdos

Garrett Cooper ngie at FreeBSD.org
Sun Dec 6 21:07:34 UTC 2015


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


More information about the svn-src-head mailing list