⬢ DragonFlyBSD Kernel Audit
DF-5797 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/vfs_syscalls.c	2026-10-12 21:04:10.265498261 +0000
+++ b/sys/kern/vfs_syscalls.c	2026-10-12 21:04:23.897321306 +0000
@@ -3846,6 +3846,18 @@
 
 				error = naccess_lva(&lva, NLC_OWN | NLC_WRITE,
 						   fp->f_cred);
+				/*
+				 * POSIX: a non-owner may only set the timestamps
+				 * to the current time (nullflag), regardless of
+				 * write permission.  Arbitrary values require
+				 * ownership or privilege.
+				 */
+				if (error == 0 && nullflag == 0 &&
+				    lva.va_uid != fp->f_cred->cr_uid) {
+					if (caps_priv_check(fp->f_cred,
+						    SYSCAP_NOVFS_SETATTR))
+						error = EPERM;
+				}
 			}
 			if (error == 0) {
 				error = setutimes(vp, &vattr, newts, nullflag);
@@ -3968,7 +3980,27 @@
 	if ((error = vn_writechk(vp)) == 0) {
 		error = vget(vp, LK_EXCLUSIVE);
 		if (error == 0) {
-			error = setutimes(vp, &vattr, newts, nullflag);
+			/*
+			 * POSIX: a non-owner may only set the timestamps
+			 * to the current time (nullflag), regardless of
+			 * write permission.  Arbitrary values require
+			 * ownership or privilege (mirrors ufs_setattr and
+			 * the can_hardlink() style used in this file).
+			 */
+			if (nullflag == 0) {
+				struct vattr ova;
+
+				if ((error = VOP_GETATTR(vp, &ova)) == 0 &&
+				    ova.va_uid != nd->nl_cred->cr_uid) {
+					if (caps_priv_check(nd->nl_cred,
+						    SYSCAP_NOVFS_SETATTR))
+						error = EPERM;
+				}
+			}
+			if (error == 0) {
+				error = setutimes(vp, &vattr, newts,
+						  nullflag);
+			}
 			vput(vp);
 		}
 	}