svn commit: r342548 - in head/sys: fs/ext2fs kern ufs/ffs ufs/ufs

Kirk McKusick mckusick at FreeBSD.org
Thu Dec 27 07:18:55 UTC 2018


Author: mckusick
Date: Thu Dec 27 07:18:53 2018
New Revision: 342548
URL: https://svnweb.freebsd.org/changeset/base/342548

Log:
  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 at 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

Modified:
  head/sys/fs/ext2fs/ext2_vnops.c
  head/sys/kern/vfs_subr.c
  head/sys/ufs/ffs/ffs_snapshot.c
  head/sys/ufs/ufs/ufs_vnops.c

Modified: head/sys/fs/ext2fs/ext2_vnops.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_vnops.c	Thu Dec 27 04:53:53 2018	(r342547)
+++ head/sys/fs/ext2fs/ext2_vnops.c	Thu Dec 27 07:18:53 2018	(r342548)
@@ -1920,6 +1920,11 @@ ext2_vinit(struct mount *mntp, struct vop_vector *fifo
 	vp = *vpp;
 	ip = VTOI(vp);
 	vp->v_type = IFTOVT(ip->i_mode);
+	/*
+	 * Only unallocated inodes should be of type VNON.
+	 */
+	if (ip->i_mode != 0 && vp->v_type == VNON)
+		return (EINVAL);
 	if (vp->v_type == VFIFO)
 		vp->v_op = fifoops;
 

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c	Thu Dec 27 04:53:53 2018	(r342547)
+++ head/sys/kern/vfs_subr.c	Thu Dec 27 07:18:53 2018	(r342548)
@@ -156,7 +156,7 @@ SYSCTL_ULONG(_vfs, OID_AUTO, mnt_free_list_batch, CTLF
  */
 enum vtype iftovt_tab[16] = {
 	VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
-	VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
+	VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VNON
 };
 int vttoif_tab[10] = {
 	0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK,

Modified: head/sys/ufs/ffs/ffs_snapshot.c
==============================================================================
--- head/sys/ufs/ffs/ffs_snapshot.c	Thu Dec 27 04:53:53 2018	(r342547)
+++ head/sys/ufs/ffs/ffs_snapshot.c	Thu Dec 27 07:18:53 2018	(r342548)
@@ -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);

Modified: head/sys/ufs/ufs/ufs_vnops.c
==============================================================================
--- head/sys/ufs/ufs/ufs_vnops.c	Thu Dec 27 04:53:53 2018	(r342547)
+++ head/sys/ufs/ufs/ufs_vnops.c	Thu Dec 27 07:18:53 2018	(r342548)
@@ -2517,6 +2517,11 @@ ufs_vinit(mntp, fifoops, vpp)
 	vp = *vpp;
 	ip = VTOI(vp);
 	vp->v_type = IFTOVT(ip->i_mode);
+	/*
+	 * Only unallocated inodes should be of type VNON.
+	 */
+	if (ip->i_mode != 0 && vp->v_type == VNON)
+		return (EINVAL);
 	if (vp->v_type == VFIFO)
 		vp->v_op = fifoops;
 	ASSERT_VOP_LOCKED(vp, "ufs_vinit");


More information about the svn-src-head mailing list