DragonFlyBSD Kernel Audit
DF-0914 / 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,21 @@
 		error = EINVAL;		/* XXX needs translation */
 		goto out;
 	}
+	/*
+	 * fs_nindir must equal fs_bsize / sizeof(ufs_daddr_t).  It is
+	 * copied verbatim into ump->um_nindir and used as the modulus for
+	 * in_off in ufs_getlbns(); a forged larger value drives OOB index
+	 * bap[in_off] in ufs_bmaparray (read path, DF-0914) and ffs_balloc
+	 * (write path, DF-0894) — up to ~16KB past the indirect-block
+	 * buffer.
+	 */
+	if (fs->fs_nindir != fs->fs_bsize / sizeof(ufs_daddr_t)) {
+		kprintf("ffs_mountfs: bad fs_nindir %d (expected %d)\n",
+		    fs->fs_nindir,
+		    (int)(fs->fs_bsize / sizeof(ufs_daddr_t)));
+		error = EINVAL;
+		goto out;
+	}
 	fs->fs_fmod = 0;
 	fs->fs_flags &= ~FS_UNCLEAN;
 	if (fs->fs_clean == 0) {