summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_syscalls.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 717bf06185d..4d18d1dbef1 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.312 2019/01/22 20:39:51 tedu Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.313 2019/01/23 00:37:51 cheloha Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -2422,6 +2422,8 @@ sys_utimes(struct proc *p, void *v, register_t *retval)
error = copyin(tvp, tv, sizeof(tv));
if (error)
return (error);
+ if (!timerisvalid(&tv[0]) || !timerisvalid(&tv[1]))
+ return (EINVAL);
TIMEVAL_TO_TIMESPEC(&tv[0], &ts[0]);
TIMEVAL_TO_TIMESPEC(&tv[1], &ts[1]);
} else
@@ -2442,13 +2444,21 @@ sys_utimensat(struct proc *p, void *v, register_t *retval)
struct timespec ts[2];
const struct timespec *tsp;
- int error;
+ int error, i;
tsp = SCARG(uap, times);
if (tsp != NULL) {
error = copyin(tsp, ts, sizeof(ts));
if (error)
return (error);
+ for (i = 0; i < nitems(ts); i++) {
+ if (ts[i].tv_nsec == UTIME_NOW)
+ continue;
+ if (ts[i].tv_nsec == UTIME_OMIT)
+ continue;
+ if (!timespecisvalid(&ts[i]))
+ return (EINVAL);
+ }
} else
ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;
@@ -2510,20 +2520,10 @@ dovutimens(struct proc *p, struct vnode *vp, struct timespec ts[2])
ts[1] = now;
}
- if (ts[0].tv_nsec != UTIME_OMIT) {
- if (ts[0].tv_nsec < 0 || ts[0].tv_nsec >= 1000000000) {
- vrele(vp);
- return (EINVAL);
- }
+ if (ts[0].tv_nsec != UTIME_OMIT)
vattr.va_atime = ts[0];
- }
- if (ts[1].tv_nsec != UTIME_OMIT) {
- if (ts[1].tv_nsec < 0 || ts[1].tv_nsec >= 1000000000) {
- vrele(vp);
- return (EINVAL);
- }
+ if (ts[1].tv_nsec != UTIME_OMIT)
vattr.va_mtime = ts[1];
- }
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
@@ -2554,6 +2554,8 @@ sys_futimes(struct proc *p, void *v, register_t *retval)
error = copyin(tvp, tv, sizeof(tv));
if (error)
return (error);
+ if (!timerisvalid(&tv[0]) || !timerisvalid(&tv[1]))
+ return (EINVAL);
TIMEVAL_TO_TIMESPEC(&tv[0], &ts[0]);
TIMEVAL_TO_TIMESPEC(&tv[1], &ts[1]);
} else
@@ -2571,13 +2573,21 @@ sys_futimens(struct proc *p, void *v, register_t *retval)
} */ *uap = v;
struct timespec ts[2];
const struct timespec *tsp;
- int error;
+ int error, i;
tsp = SCARG(uap, times);
if (tsp != NULL) {
error = copyin(tsp, ts, sizeof(ts));
if (error)
return (error);
+ for (i = 0; i < nitems(ts); i++) {
+ if (ts[i].tv_nsec == UTIME_NOW)
+ continue;
+ if (ts[i].tv_nsec == UTIME_OMIT)
+ continue;
+ if (!timespecisvalid(&ts[i]))
+ return (EINVAL);
+ }
} else
ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;