DragonFlyBSD Kernel Audit
DF-3027 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/fuse/fuse_vnops.c
+++ b/sys/vfs/fuse/fuse_vnops.c
@@ -309,11 +309,21 @@
 	struct fuse_attr_out *fao;
 	int error;
 
-	if (fuse_test_dead(fmp))
+	/*
+	 * DF-3027: always fill in *a_vap on success; callers (vn_stat)
+	 * use an uninitialized vattr and copy it to userland otherwise.
+	 */
+	if (fuse_test_dead(fmp)) {
+		memset(vap, 0, sizeof(*vap));
+		vap->va_type = vp->v_type;
 		return 0;
-
-	if (fuse_test_nosys(fmp, FUSE_GETATTR))
+	}
+
+	if (fuse_test_nosys(fmp, FUSE_GETATTR)) {
+		memset(vap, 0, sizeof(*vap));
+		vap->va_type = vp->v_type;
 		return 0;
+	}
 
 	if (fnp->attrgood == 0) {
 		/*
@@ -328,8 +338,12 @@
 #endif
 		error = fuse_ipc_tx(fip);
 		if (error) {
-			if (error == ENOSYS)
+			if (error == ENOSYS) {
+				/* DF-3027: no success with uninit vattr */
+				memset(vap, 0, sizeof(*vap));
+				vap->va_type = vp->v_type;
 				error = 0;
+			}
 			if (error == ENOTCONN && (vp->v_flag & VROOT)) {
 				memset(vap, 0, sizeof(*vap));
 				vap->va_type = vp->v_type;