DragonFlyBSD Kernel Audit
DF-3024 / fix.diff
← back to finding ↓ download raw
--- sys/vfs/tmpfs/tmpfs_subr.c
+++ sys/vfs/tmpfs/tmpfs_subr.c
@@ -1293,6 +1293,7 @@
 	      int vaflags, struct ucred *cred)
 {
 	struct tmpfs_node *node;
+	int error;
 
 	KKASSERT(vn_islocked(vp));
 
@@ -1306,6 +1307,19 @@
 	if (node->tn_flags & (IMMUTABLE | APPEND))
 		return EPERM;
 
+	/*
+	 * Forging explicit (non-current) timestamps is restricted to the
+	 * file owner or privilege; a non-owner with write access may only
+	 * set the times to the current time (VA_UTIMES_NULL).  Mirrors
+	 * ufs_vnops.c / ext2 / msdosfs / hpfs.
+	 */
+	if (cred->cr_uid != node->tn_uid &&
+	    (error = caps_priv_check(cred, SYSCAP_NOVFS_SETATTR)) != 0 &&
+	    ((vaflags & VA_UTIMES_NULL) == 0 ||
+	     (error = VOP_EACCESS(vp, VWRITE, cred)) != 0)) {
+		return error;
+	}
+
 	TMPFS_NODE_LOCK(node);
 	if (atime->tv_sec != VNOVAL && atime->tv_nsec != VNOVAL)
 		node->tn_status |= TMPFS_NODE_ACCESSED;