Test whether the filesystem is an LFS before trying to read the alternate

superblock (whose disk address is stored in the primary superblock).  Also,
refuse to mount a filesystem whose superblocks overlap or where the alt.
superblock has a lower disk address than the primary superblock.

Solves PR#10001.
This commit is contained in:
perseant 2000-04-29 00:23:00 +00:00
parent 22cfbf2cbb
commit 37f567639c

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vfsops.c,v 1.49 2000/04/23 21:10:27 perseant Exp $ */
/* $NetBSD: lfs_vfsops.c,v 1.50 2000/04/29 00:23:00 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -366,6 +366,7 @@ lfs_mountfs(devvp, mp, p)
/* Don't free random space on error. */
bp = NULL;
abp = NULL;
ump = NULL;
/* Read in the superblock. */
@ -374,19 +375,6 @@ lfs_mountfs(devvp, mp, p)
goto out;
dfs = (struct dlfs *)bp->b_data;
/*
* Check the second superblock to see which is newer; then mount
* using the older of the two. This is necessary to ensure that
* the filesystem is valid if it was not unmounted cleanly.
*/
error = bread(devvp, dfs->dlfs_sboffs[1], LFS_SBPAD, cred, &abp);
if (error)
goto out;
adfs = (struct dlfs *)abp->b_data;
if (adfs->dlfs_tstamp < dfs->dlfs_tstamp) /* XXX KS - 1s resolution? */
dfs = adfs;
/* Check the basics. */
if (dfs->dlfs_magic != LFS_MAGIC || dfs->dlfs_bsize > MAXBSIZE ||
dfs->dlfs_version > LFS_VERSION ||
@ -395,6 +383,28 @@ lfs_mountfs(devvp, mp, p)
goto out;
}
/*
* Check the second superblock to see which is newer; then mount
* using the older of the two. This is necessary to ensure that
* the filesystem is valid if it was not unmounted cleanly.
*/
if (dfs->dlfs_sboffs[1] &&
dfs->dlfs_sboffs[1]-(LFS_LABELPAD/size) > LFS_SBPAD/size)
{
error = bread(devvp, dfs->dlfs_sboffs[1], LFS_SBPAD, cred, &abp);
if (error)
goto out;
adfs = (struct dlfs *)abp->b_data;
if (adfs->dlfs_tstamp < dfs->dlfs_tstamp) /* XXX 1s? */
dfs = adfs;
} else {
printf("lfs_mountfs: invalid alt superblock daddr=0x%x\n",
dfs->dlfs_sboffs[1]);
error = EINVAL;
goto out;
}
/* Allocate the mount structure, copy the superblock into it. */
fs = malloc(sizeof(struct lfs), M_UFSMNT, M_WAITOK);
memcpy(&fs->lfs_dlfs, dfs, sizeof(struct dlfs));