DragonFlyBSD Kernel Audit
DF-0794 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/ufs/ffs_vfsops.c b/sys/vfs/ufs/ffs_vfsops.c
--- a/sys/vfs/ufs/ffs_vfsops.c
+++ b/sys/vfs/ufs/ffs_vfsops.c
@@ -644,6 +644,19 @@
 		error = EINVAL;		/* XXX needs translation */
 		goto out;
 	}
+	/*
+	 * Validate superblock geometry used as a divisor in the block/inode
+	 * allocators.  fs_ncg, fs_ipg, fs_fpg and fs_frag are all attacker
+	 * controllable from the on-disk superblock and a zero value drives
+	 * divide-by-zero traps in ffs_dirpref/ffs_valloc/ffs_hashalloc
+	 * (DF-0794: fs_ncg==0 -> fatal trap 18 in ffs_valloc).
+	 */
+	if (fs->fs_ncg <= 0 || fs->fs_ipg <= 0 || fs->fs_frag <= 0) {
+		kprintf("ffs_mountfs: corrupt superblock: ncg=%d ipg=%d frag=%d\n",
+		    fs->fs_ncg, fs->fs_ipg, fs->fs_frag);
+		error = EINVAL;
+		goto out;
+	}
 	fs->fs_fmod = 0;
 	fs->fs_flags &= ~FS_UNCLEAN;
 	if (fs->fs_clean == 0) {