DF-3001 / fix.diff
--- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -2342,6 +2342,21 @@ } break; } + if (vap->va_atime.tv_sec != VNOVAL || + vap->va_mtime.tv_sec != VNOVAL) { + if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) { + error = EROFS; + goto done; + } + if (ap->a_cred->cr_uid != + hammer_to_unix_xid(&ip->ino_data.uid) && + (error = caps_priv_check(ap->a_cred, + SYSCAP_NOVFS_SETATTR)) != 0 && + ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || + (error = VOP_EACCESS(ap->a_vp, VWRITE, ap->a_cred)) != 0)) { + goto done; + } + } if (vap->va_atime.tv_sec != VNOVAL) { ip->ino_data.atime = hammer_timespec_to_time(&vap->va_atime); modflags |= HAMMER_INODE_ATIME; @@ -2351,6 +2366,7 @@ ip->ino_data.mtime = hammer_timespec_to_time(&vap->va_mtime); modflags |= HAMMER_INODE_MTIME; kflags |= NOTE_ATTRIB; + vclrflags(ap->a_vp, VLASTWRITETS); } if (vap->va_mode != (mode_t)VNOVAL) { |