Mon Aug 9 15:50:13 2010 UTC ()
Return error if we try to mount a file system with block size > MAXBSIZE.

Note: there is a billion ways to make the kernel panic by trying
to mount a garbage file system and I don't imagine we'll ever get
close to fixing even half of them.  However, for this one failing
gracefully is a bonus since Xen DomU only does 32k MAXBSIZE and
the 64k MAXBSIZE file systems are out there (PR port-xen/43727).

Tested by compiling sys/rump with CPPFLAGS+=-DMAXPHYS=32768 (all
tests in tests/fs still pass).  I don't know how we're going to
translate this into an easy regression test, though.  Maybe with
a hacked newfs?


(pooka)
diff -r1.260 -r1.261 src/sys/ufs/ffs/ffs_vfsops.c

cvs diff -r1.260 -r1.261 src/sys/ufs/ffs/ffs_vfsops.c (expand / switch to context diff)
--- src/sys/ufs/ffs/ffs_vfsops.c 2010/07/21 17:52:13 1.260
+++ src/sys/ufs/ffs/ffs_vfsops.c 2010/08/09 15:50:13 1.261
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffs_vfsops.c,v 1.260 2010/07/21 17:52:13 hannken Exp $	*/
+/*	$NetBSD: ffs_vfsops.c,v 1.261 2010/08/09 15:50:13 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.260 2010/07/21 17:52:13 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.261 2010/08/09 15:50:13 pooka Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -828,6 +828,7 @@
 	int32_t *lp;
 	kauth_cred_t cred;
 	u_int32_t sbsize = 8192;	/* keep gcc happy*/
+	int32_t fsbsize;
 
 	dev = devvp->v_rdev;
 	cred = l ? l->l_cred : NOCRED;
@@ -886,21 +887,25 @@
 		if (fs->fs_magic == FS_UFS1_MAGIC) {
 			sbsize = fs->fs_sbsize;
 			fstype = UFS1;
+			fsbsize = fs->fs_bsize;
 #ifdef FFS_EI
 			needswap = 0;
 		} else if (fs->fs_magic == bswap32(FS_UFS1_MAGIC)) {
 			sbsize = bswap32(fs->fs_sbsize);
 			fstype = UFS1;
+			fsbsize = bswap32(fs->fs_bsize);
 			needswap = 1;
 #endif
 		} else if (fs->fs_magic == FS_UFS2_MAGIC) {
 			sbsize = fs->fs_sbsize;
 			fstype = UFS2;
+			fsbsize = fs->fs_bsize;
 #ifdef FFS_EI
 			needswap = 0;
 		} else if (fs->fs_magic == bswap32(FS_UFS2_MAGIC)) {
 			sbsize = bswap32(fs->fs_sbsize);
 			fstype = UFS2;
+			fsbsize = bswap32(fs->fs_bsize);
 			needswap = 1;
 #endif
 		} else
@@ -932,6 +937,13 @@
 		/* Validate size of superblock */
 		if (sbsize > MAXBSIZE || sbsize < sizeof(struct fs))
 			continue;
+
+		/* Check that we can handle the file system blocksize */
+		if (fsbsize > MAXBSIZE) {
+			printf("ffs_mountfs: block size (%d) > MAXBSIZE (%d)",
+			    fsbsize, MAXBSIZE);
+			continue;
+		}
 
 		/* Ok seems to be a good superblock */
 		break;