Subject: kern/3933: corrupted ffs filesystem panics system when mounting
To: None <gnats-bugs@gnats.netbsd.org>
From: None <haszlaki@uiuc.edu>
List: netbsd-bugs
Date: 08/02/1997 21:21:12
>Number:         3933
>Category:       kern
>Synopsis:       Corrupted ffs filesystem can crash netbsd when mounting
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Aug  2 19:50:02 1997
>Last-Modified:
>Originator:     Eric Haszlakiewicz
>Organization:
>Release:        1.2G
>Environment:
System: NetBSD realms.wwa.com 1.2G NetBSD 1.2G (REALMS) #9: Sat Aug 2 20:00:12 CDT 1997 root@realms.wwa.com:/usr/src/sys/arch/i386/compile/REALMS i386


>Description:
	A corrupted ffs filesystem with unreasonable values for fs_sbsize
	or fs_cssize will panic the system.  This occurs because these
	values get passed directly to malloc without any checks to see
	it they are within a valid range:  malloc barfs, the system panics.
>How-To-Repeat:
	Create a ffs filesystem with an unreasonable value for 
	fs_sbsize or fs_cssize.  Run mount_ffs on it.
>Fix:
	Apply this patch to src/sys/ufs/ffs/ffs_vfsops.c.
	(the cast to u_int32_t from int32_t seems to be neccessary
	for the comparison to work.  I don't know why.  Shouldn't
	just (e.g.) (fs->fs_sbsize > SBSIZE) work?)

--- ffs_vfsops.c.old	Sat Aug  2 21:04:27 1997
+++ ffs_vfsops.c	Sat Aug  2 21:08:23 1997
@@ -466,8 +466,16 @@
 	if (error)
 		goto out;
 	fs = (struct fs *)bp->b_data;
+
+	/* Check magic.  Make sure block size, superblock size and   */
+	/* cylinder group summary area are a reasonable size.        */
+	/* Unless these get checked a corrupted filesystem can panic */
+	/* the system when we pass an unreasonable size to malloc.   */
 	if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE
-	    || fs->fs_bsize < sizeof(struct fs)) {
+	    || fs->fs_bsize < sizeof(struct fs)
+	    || (u_int32_t)fs->fs_sbsize > SBSIZE
+	    || (u_int32_t)fs->fs_sbsize < sizeof(struct fs)
+	    || (u_int32_t)fs->fs_cssize > MAXCSBUFS * sizeof(struct csum)) {
 		error = EINVAL;		/* XXX needs translation */
 		goto out;
 	}

>Audit-Trail:
>Unformatted: