DragonFlyBSD Kernel Audit
DF-2629 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/hammer2/hammer2_vnops.c b/sys/vfs/hammer2/hammer2_vnops.c
index 1111111..3333333 100644
@@ -558,6 +558,28 @@
 		}
 	}
 
+	/*
+	 * Timestamp updates require the same authority UFS enforces in
+	 * ufs_setattr() (sys/vfs/ufs/ufs_vnops.c): the file owner, a
+	 * privileged caller, or (VA_UTIMES_NULL set AND write access).
+	 * The syscall layer only pre-filters owner-or-write-access via
+	 * nlookup (NLC_OWN|NLC_WRITE in kern_utimensat), which lets any
+	 * write-permitted non-owner through to VOP_SETATTR with explicit
+	 * timestamps - hammer2 must reject those itself or mtime can be
+	 * forged.
+	 */
+	if (vap->va_mtime.tv_sec != VNOVAL ||
+	    vap->va_atime.tv_sec != VNOVAL) {
+		uid_t cur_uid = hammer2_to_unix_xid(&ip->meta.uid);
+
+		if (ap->a_cred->cr_uid != cur_uid &&
+		    (error = caps_priv_check(ap->a_cred,
+			     SYSCAP_NOVFS_SETATTR)) != 0 &&
+		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
+		     (error = VOP_EACCESS(vp, VWRITE, ap->a_cred)) != 0)) {
+			goto done;
+		}
+	}
 	if (vap->va_mtime.tv_sec != VNOVAL) {
 		hammer2_inode_modify(ip);
 		ip->meta.mtime = hammer2_timespec_to_time(&vap->va_mtime);