diff options
author | tobias <tobias@openbsd.org> | 2014-06-14 15:23:45 +0000 |
---|---|---|
committer | tobias <tobias@openbsd.org> | 2014-06-14 15:23:45 +0000 |
commit | fb704eb61c011c7e3795c65f8bf86c16e3e8898b (patch) | |
tree | 44739ead6be6c35fbc804b17edb42fb0f602ec7e /sbin/fsck_msdos | |
parent | Fix regression of 1.16: write fsinfo, not block into FSInfo region. (diff) | |
download | wireguard-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.c | 71 |
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; } |