DF-0914 / fix.diff
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) { |