From owner-svn-src-head@freebsd.org Sun Dec 6 21:07:34 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 74FBD9A073B; Sun, 6 Dec 2015 21:07:34 +0000 (UTC) (envelope-from ngie@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4926814E5; Sun, 6 Dec 2015 21:07:34 +0000 (UTC) (envelope-from ngie@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tB6L7XIw055707; Sun, 6 Dec 2015 21:07:33 GMT (envelope-from ngie@FreeBSD.org) Received: (from ngie@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tB6L7X6h055706; Sun, 6 Dec 2015 21:07:33 GMT (envelope-from ngie@FreeBSD.org) Message-Id: <201512062107.tB6L7X6h055706@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ngie set sender to ngie@FreeBSD.org using -f From: Garrett Cooper Date: Sun, 6 Dec 2015 21:07:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r291908 - head/sbin/newfs_msdos X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 06 Dec 2015 21:07:34 -0000 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 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; } /*