summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2002-12-02 19:30:37 +0000
committermckusick <mckusick@FreeBSD.org>2002-12-02 19:30:37 +0000
commit87d881b0faa9c2ac68c80ee73ab7905a5be6cc9f (patch)
treec5cbcbee2148577e606567de3414c0405ed46eab /sbin/fsck_ffs
parentbcf5c2745def03a4aaf50c4922ff92b0876f603b (diff)
downloadFreeBSD-src-87d881b0faa9c2ac68c80ee73ab7905a5be6cc9f.zip
FreeBSD-src-87d881b0faa9c2ac68c80ee73ab7905a5be6cc9f.tar.gz
Verify that alternate superblocks have a correct magic number before
trying to use them. Set a minimum value for numdirs when using an alternate superblock to avoid spurious numdirs == 0 error. Calculate new fields when using an alternate superblock from a UFS1 filesystem to avoid segment faulting. Sponsored by: DARPA & NAI Labs.
Diffstat (limited to 'sbin/fsck_ffs')
-rw-r--r--sbin/fsck_ffs/setup.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 87927dc..6cbdf26 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -258,12 +258,8 @@ setup(char *dev)
(unsigned)(sizeof(struct inostatlist) * (sblock.fs_ncg)));
goto badsb;
}
- numdirs = sblock.fs_cstotal.cs_ndir;
+ numdirs = MAX(sblock.fs_cstotal.cs_ndir, 128);
dirhash = numdirs;
- if (numdirs == 0) {
- printf("numdirs is zero, try using an alternate superblock\n");
- goto badsb;
- }
inplast = 0;
listmax = numdirs + 10;
inpsort = (struct inoinfo **)calloc((unsigned)listmax,
@@ -305,6 +301,12 @@ readsb(int listerr)
super = bflag;
if ((bread(fsreadfd, (char *)&sblock, super, (long)SBLOCKSIZE)))
return (0);
+ if (sblock.fs_magic != FS_UFS1_MAGIC &&
+ sblock.fs_magic != FS_UFS2_MAGIC) {
+ fprintf(stderr, "%d is not a file system superblock\n",
+ bflag);
+ return (0);
+ }
} else {
for (i = 0; sblock_try[i] != -1; i++) {
super = sblock_try[i] / dev_bsize;
@@ -333,10 +335,8 @@ readsb(int listerr)
dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
sblk.b_bno = super / dev_bsize;
sblk.b_size = SBLOCKSIZE;
- if (bflag) {
- havesb = 1;
- return (1);
- }
+ if (bflag)
+ goto out;
/*
* Compare all fields that should not differ in alternate super block.
* When an alternate super-block is specified this check is skipped.
@@ -369,6 +369,7 @@ readsb(int listerr)
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
return (0);
}
+out:
/*
* If not yet done, update UFS1 superblock with new wider fields.
*/
OpenPOWER on IntegriCloud