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) {