diff options
author | Kirk McKusick <mckusick@FreeBSD.org> | 2018-12-27 07:18:53 +0000 |
---|---|---|
committer | Kirk McKusick <mckusick@FreeBSD.org> | 2018-12-27 07:18:53 +0000 |
commit | c0029546f8b31e3013e75df01cadb4cf1505c2c2 (patch) | |
tree | d2d7de5ca9ccd27d521ae4b44e282f314752efa7 /sys/ufs/ffs/ffs_snapshot.c | |
parent | af907c40da9b359a50e2aea2bfbf6d16bffe55f4 (diff) | |
download | src-c0029546f8b31e3013e75df01cadb4cf1505c2c2.tar.gz src-c0029546f8b31e3013e75df01cadb4cf1505c2c2.zip |
When loading an inode from disk, verify that its mode is valid.
If invalid, return EINVAL. Note that inode check-hashes greatly
reduce the chance that these errors will go undetected.
Reported by: Christopher Krah <krah@protonmail.com>
Reported as: FS-5-UFS-2: Denial Of Service in nmount-3 (ffs_read)
Reviewed by: kib
MFC after: 1 week
Sponsored by: Netflix
M sys/fs/ext2fs/ext2_vnops.c
M sys/kern/vfs_subr.c
M sys/ufs/ffs/ffs_snapshot.c
M sys/ufs/ufs/ufs_vnops.c
Notes
Notes:
svn path=/head/; revision=342548
Diffstat (limited to 'sys/ufs/ffs/ffs_snapshot.c')
-rw-r--r-- | sys/ufs/ffs/ffs_snapshot.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index e321df8b93fe..26185a28e4d8 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -2001,15 +2001,19 @@ ffs_snapshot_mount(mp) continue; } ip = VTOI(vp); - if (!IS_SNAPSHOT(ip) || ip->i_size == + if (vp->v_type != VREG) { + reason = "non-file snapshot"; + } else if (!IS_SNAPSHOT(ip)) { + reason = "non-snapshot"; + } else if (ip->i_size == lblktosize(fs, howmany(fs->fs_size, fs->fs_frag))) { - if (!IS_SNAPSHOT(ip)) { - reason = "non-snapshot"; - } else { - reason = "old format snapshot"; - (void)ffs_truncate(vp, (off_t)0, 0, NOCRED); - (void)ffs_syncvnode(vp, MNT_WAIT, 0); - } + reason = "old format snapshot"; + (void)ffs_truncate(vp, (off_t)0, 0, NOCRED); + (void)ffs_syncvnode(vp, MNT_WAIT, 0); + } else { + reason = NULL; + } + if (reason != NULL) { printf("ffs_snapshot_mount: %s inode %d\n", reason, fs->fs_snapinum[snaploc]); vput(vp); |