diff options
-rw-r--r-- | sys/kern/kern_exec.c | 14 | ||||
-rw-r--r-- | sys/sys/vnode.h | 1 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 11 |
3 files changed, 25 insertions, 1 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 204b284..78d86ce 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -284,7 +284,7 @@ do_execve(td, args, mac_p) register_t *stack_base; int error, len, i; struct image_params image_params, *imgp; - struct vattr attr; + struct vattr atimeattr, attr; int (*img_first)(struct image_params *); struct pargs *oldargs = NULL, *newargs = NULL; struct sigacts *oldsigacts, *newsigacts; @@ -695,6 +695,18 @@ interpret: exec_setregs(td, imgp->entry_addr, (u_long)(uintptr_t)stack_base, imgp->ps_strings); + /* + * Here we should update the access time of the file. This must + * be implemented by the underlying filesystem in the same way as + * access timestamps for a VOP_READ() because we want to avoid + * blocking and/or I/O, and have not called vn_start_write(). + */ + if ((imgp->vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0) { + VATTR_NULL(&atimeattr); + atimeattr.va_vaflags |= VA_EXECVE_ATIME; + (void)VOP_SETATTR(imgp->vp, &atimeattr, td->td_ucred, td); + } + done1: /* * Free any resources malloc'd earlier that we didn't use. diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index d6608c2..3cbb109 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -284,6 +284,7 @@ struct vattr { */ #define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */ #define VA_EXCLUSIVE 0x02 /* exclusive create request */ +#define VA_EXECVE_ATIME 0x04 /* setting atime for execve */ /* * Flags for ioflag. (high 16 bits used to ask for read-ahead and diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 36dad08..720e7bb 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -443,6 +443,17 @@ ufs_setattr(ap) ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { return (EINVAL); } + /* + * Update the file's access time when it has been executed. We are + * doing this here to specifically avoid some of the checks done + * below -- this operation is done by request of the kernel and + * should bypass some security checks. Things like read-only + * checks get handled by other levels (e.g., ffs_update()). + */ + if (vap->va_vaflags & VA_EXECVE_ATIME) { + ip->i_flag |= IN_ACCESS; + return (0); + } if (vap->va_flags != VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); |