summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_exec.c14
-rw-r--r--sys/sys/vnode.h1
-rw-r--r--sys/ufs/ufs/ufs_vnops.c11
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);
OpenPOWER on IntegriCloud