DragonFlyBSD Kernel Audit
DF-0718 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netproto/smb/smb_dev.c b/sys/netproto/smb/smb_dev.c
index 0000000..1111111 100644
--- a/sys/netproto/smb/smb_dev.c
+++ b/sys/netproto/smb/smb_dev.c
@@ -392,6 +392,18 @@
 	if (fp == NULL)
 		return EBADF;
 
+	/*
+	 * The fd must reference a vnode.  Without this check a socket, pipe,
+	 * kqueue, or other non-vnode fd is type-confused: its f_data (a
+	 * struct socket/pipe/kqueue) is cast to a vnode and then read by
+	 * vn_todev() at vnode offsets, which can return garbage (wild
+	 * SMB_GETDEV deref) or trip KKASSERT(vp->v_rdev != NULL).
+	 */
+	if (fp->f_type != DTYPE_VNODE) {
+		error = EINVAL;
+		goto done;
+	}
+
 	vp = (struct vnode*)fp->f_data;
 	if (vp == NULL) {
 		error = EBADF;