diff options
-rw-r--r-- | sys/kern/vfs_syscalls.c | 40 |
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; |