--- 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;