summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_msdos
diff options
context:
space:
mode:
authortobias <tobias@openbsd.org>2014-06-14 15:23:45 +0000
committertobias <tobias@openbsd.org>2014-06-14 15:23:45 +0000
commitfb704eb61c011c7e3795c65f8bf86c16e3e8898b (patch)
tree44739ead6be6c35fbc804b17edb42fb0f602ec7e /sbin/fsck_msdos
parentFix regression of 1.16: write fsinfo, not block into FSInfo region. (diff)
downloadwireguard-openbsd-fb704eb61c011c7e3795c65f8bf86c16e3e8898b.tar.xz
wireguard-openbsd-fb704eb61c011c7e3795c65f8bf86c16e3e8898b.zip
Fix memory leaks in bootblock handling.
ok krw@
Diffstat (limited to 'sbin/fsck_msdos')
-rw-r--r--sbin/fsck_msdos/boot.c71
1 files changed, 42 insertions, 29 deletions
diff --git a/sbin/fsck_msdos/boot.c b/sbin/fsck_msdos/boot.c
index 528da2b1e8a..e05265449a9 100644
--- a/sbin/fsck_msdos/boot.c
+++ b/sbin/fsck_msdos/boot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot.c,v 1.18 2014/06/14 15:21:27 tobias Exp $ */
+/* $OpenBSD: boot.c,v 1.19 2014/06/14 15:23:45 tobias Exp $ */
/* $NetBSD: boot.c,v 1.5 1997/10/17 11:19:23 ws Exp $ */
/*
@@ -47,37 +47,37 @@
int
readboot(int dosfs, struct bootblock *boot)
{
- u_char *block;
- u_char *fsinfo;
- u_char *backup;
+ u_char *block = NULL;
+ u_char *fsinfo = NULL;
+ u_char *backup = NULL;
int ret = FSOK, secsize = lab.d_secsize, fsinfosz;
off_t o;
ssize_t n;
if (secsize < DOSBOOTBLOCKSIZE) {
xperror("sector size < DOSBOOTBLOCKSIZE");
- return (FSFATAL);
+ goto fail;
}
if (DOSBOOTBLOCKSIZE != DEV_BSIZE) {
xperror("DOSBOOTBLOCKSIZE != DEV_BSIZE");
- return (FSFATAL);
+ goto fail;
}
block = malloc(secsize);
if (block == NULL) {
xperror("could not malloc boot block");
- return FSFATAL;
+ goto fail;
}
if ((o = lseek(dosfs, 0, SEEK_SET)) == -1) {
xperror("could not seek boot block");
- return FSFATAL;
+ goto fail;
}
n = read(dosfs, block, secsize);
if (n == -1 || n != secsize) {
xperror("could not read boot block");
- return (FSFATAL);
+ goto fail;
}
if (block[510] != 0x55 || block[511] != 0xaa) {
@@ -92,12 +92,12 @@ readboot(int dosfs, struct bootblock *boot)
boot->BytesPerSec = block[11] + (block[12] << 8);
if (boot->BytesPerSec == 0 || boot->BytesPerSec != secsize) {
pfatal("Invalid sector size: %u\n", boot->BytesPerSec);
- return (FSFATAL);
+ goto fail;
}
boot->SecPerClust = block[13];
if (boot->SecPerClust == 0) {
pfatal("Invalid cluster size: %u\n", boot->SecPerClust);
- return (FSFATAL);
+ goto fail;
}
boot->ResSectors = block[14] + (block[15] << 8);
boot->FATs = block[16];
@@ -124,7 +124,7 @@ readboot(int dosfs, struct bootblock *boot)
/* Correct? XXX */
pfatal("Unknown filesystem version: %x.%x\n",
block[43], block[42]);
- return FSFATAL;
+ goto fail;
}
boot->RootCl = block[44] + (block[45] << 8)
+ (block[46] << 16) + (block[47] << 24);
@@ -134,7 +134,7 @@ readboot(int dosfs, struct bootblock *boot)
o = lseek(dosfs, boot->FSInfo * secsize, SEEK_SET);
if (o == -1 || o != boot->FSInfo * secsize) {
xperror("could not seek fsinfo block");
- return FSFATAL;
+ goto fail;
}
if ((2 * DOSBOOTBLOCKSIZE) < secsize)
@@ -144,12 +144,12 @@ readboot(int dosfs, struct bootblock *boot)
fsinfo = malloc(fsinfosz);
if (fsinfo == NULL) {
xperror("could not malloc fsinfo");
- return FSFATAL;
+ goto fail;
}
n = read(dosfs, fsinfo, fsinfosz);
if (n == -1 || n != fsinfosz) {
xperror("could not read fsinfo block");
- return FSFATAL;
+ goto fail;
}
if (memcmp(fsinfo, "RRaA", 4)
@@ -177,12 +177,12 @@ readboot(int dosfs, struct bootblock *boot)
SEEK_SET);
if (o == -1 || o != boot->FSInfo * secsize) {
xperror("Unable to seek FSInfo");
- return FSFATAL;
+ goto fail;
}
n = write(dosfs, fsinfo, fsinfosz);
if (n == -1 || n != fsinfosz) {
xperror("Unable to write FSInfo");
- return FSFATAL;
+ goto fail;
}
ret = FSBOOTMOD;
} else
@@ -200,17 +200,17 @@ readboot(int dosfs, struct bootblock *boot)
o = lseek(dosfs, boot->Backup * secsize, SEEK_SET);
if (o == -1 || o != boot->Backup * secsize) {
xperror("could not seek backup bootblock");
- return (FSFATAL);
+ goto fail;
}
backup = malloc(2 * secsize); /* In case we check fsinfo. */
if (backup == NULL) {
xperror("could not malloc backup boot block");
- return FSFATAL;
+ goto fail;
}
n = read(dosfs, backup, secsize);
if (n == -1 || n != secsize) {
xperror("could not read backup bootblock");
- return FSFATAL;
+ goto fail;
}
/*
@@ -229,7 +229,7 @@ readboot(int dosfs, struct bootblock *boot)
}
if (memcmp(block + 11, backup + 11, 79)) {
pfatal("backup doesn't compare to primary bootblock\n");
- return FSFATAL;
+ goto fail;
}
/* Check backup FSInfo? XXX */
}
@@ -256,7 +256,7 @@ readboot(int dosfs, struct bootblock *boot)
else {
pfatal("Filesystem too big (%u clusters) for non-FAT32 partition\n",
boot->NumClusters);
- return FSFATAL;
+ goto fail;
}
switch (boot->ClustMask) {
@@ -274,20 +274,28 @@ readboot(int dosfs, struct bootblock *boot)
if (boot->NumFatEntries < boot->NumClusters) {
pfatal("FAT size too small, %u entries won't fit into %u sectors\n",
boot->NumClusters, boot->FATsecs);
- return (FSFATAL);
+ goto fail;
}
boot->ClusterSize = boot->SecPerClust * secsize;
boot->NumFiles = 1;
boot->NumFree = 0;
+ free(backup);
+ free(block);
+ free(fsinfo);
return ret;
+fail:
+ free(backup);
+ free(block);
+ free(fsinfo);
+ return FSFATAL;
}
int
writefsinfo(int dosfs, struct bootblock *boot)
{
- u_char *fsinfo;
+ u_char *fsinfo = NULL;
int secsize = lab.d_secsize, fsinfosz;
off_t o;
ssize_t n;
@@ -300,19 +308,19 @@ writefsinfo(int dosfs, struct bootblock *boot)
fsinfo = malloc(fsinfosz);
if (fsinfo == NULL) {
xperror("could not malloc fsinfo block");
- return FSFATAL;
+ goto fail;
}
o = lseek(dosfs, boot->FSInfo * secsize, SEEK_SET);
if (o == -1 || o != boot->FSInfo * secsize) {
xperror("could not seek fsinfo block");
- return FSFATAL;
+ goto fail;
}
n = read(dosfs, fsinfo, fsinfosz);
if (n == -1 || n != fsinfosz) {
xperror("could not read fsinfo block");
- return FSFATAL;
+ goto fail;
}
fsinfo[0x1e8] = (u_char)boot->FSFree;
@@ -327,14 +335,16 @@ writefsinfo(int dosfs, struct bootblock *boot)
o = lseek(dosfs, o, SEEK_SET);
if (o == -1 || o != boot->FSInfo * boot->BytesPerSec) {
xperror("Unable to seek FSInfo");
- return FSFATAL;
+ goto fail;
}
n = write(dosfs, fsinfo, fsinfosz);
if (n == -1 || n != fsinfosz) {
xperror("Unable to write FSInfo");
- return FSFATAL;
+ goto fail;
}
+ free(fsinfo);
+
/*
* Technically, we should return FSBOOTMOD here.
*
@@ -347,4 +357,7 @@ writefsinfo(int dosfs, struct bootblock *boot)
* fact that it was incorrect.
*/
return 0;
+fail:
+ free(fsinfo);
+ return FSFATAL;
}