summaryrefslogtreecommitdiff
path: root/sbin/fsck_ffs/setup.c
diff options
context:
space:
mode:
authorGrigoriy Orlov <gluk@cvs.openbsd.org>2001-04-13 02:39:07 +0000
committerGrigoriy Orlov <gluk@cvs.openbsd.org>2001-04-13 02:39:07 +0000
commit9bff9fb87213262bc5d1afd9333ad540d9e99c54 (patch)
tree5797ca5b1e346d54d4606ff7293258862d4b223b /sbin/fsck_ffs/setup.c
parent5af2b89b71f9bb495e071539ea9548813c712c7c (diff)
Fix overflow in superblock. From FreeBSD.
FreeBSD's log: > The ffs superblock includes a 128-byte region for use by temporary > in-core pointers to summary information. An array in this region > (fs_csp) could overflow on filesystems with a very large number of > cylinder groups (~16000 on i386 with 8k blocks). When this happens, > other fields in the superblock get corrupted, and fsck refuses to > check the filesystem. > > Solve this problem by replacing the fs_csp array in 'struct fs' > with a single pointer, and add padding to keep the length of the > 128-byte region fixed. Update the kernel and userland utilities > to use just this single pointer. > > With this change, the kernel no longer makes use of the superblock > fields 'fs_csshift' and 'fs_csmask'. Add a comment to newfs/mkfs.c > to indicate that these fields must be calculated for compatibility > with older kernels. art@ ok.
Diffstat (limited to 'sbin/fsck_ffs/setup.c')
-rw-r--r--sbin/fsck_ffs/setup.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 624efbe3dac..1852b6fdbf5 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setup.c,v 1.9 2001/04/06 20:43:31 gluk Exp $ */
+/* $OpenBSD: setup.c,v 1.10 2001/04/13 02:39:05 gluk Exp $ */
/* $NetBSD: setup.c,v 1.27 1996/09/27 22:45:19 christos Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94";
#else
-static char rcsid[] = "$OpenBSD: setup.c,v 1.9 2001/04/06 20:43:31 gluk Exp $";
+static char rcsid[] = "$OpenBSD: setup.c,v 1.10 2001/04/13 02:39:05 gluk Exp $";
#endif
#endif /* not lint */
@@ -328,11 +328,11 @@ setup(dev)
* read in the summary info.
*/
asked = 0;
+ sblock.fs_csp = calloc(1, sblock.fs_cssize);
for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
size = sblock.fs_cssize - i < sblock.fs_bsize ?
sblock.fs_cssize - i : sblock.fs_bsize;
- sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size);
- if (bread(fsreadfd, (char *)sblock.fs_csp[j],
+ if (bread(fsreadfd, (char *)sblock.fs_csp + i,
fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
size) != 0 && !asked) {
pfatal("BAD SUMMARY INFORMATION");
@@ -456,8 +456,8 @@ readsb(listerr)
altsblock.fs_optim = sblock.fs_optim;
altsblock.fs_rotdelay = sblock.fs_rotdelay;
altsblock.fs_maxbpg = sblock.fs_maxbpg;
- memcpy(altsblock.fs_csp, sblock.fs_csp,
- sizeof sblock.fs_csp);
+ memcpy(altsblock.fs_ocsp, sblock.fs_ocsp, sizeof sblock.fs_ocsp);
+ altsblock.fs_csp = sblock.fs_csp;
altsblock.fs_maxcluster = sblock.fs_maxcluster;
altsblock.fs_contigdirs = sblock.fs_contigdirs;
altsblock.fs_avgfilesize = sblock.fs_avgfilesize;