summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2018-05-22 19:15:23 +0000
committercheloha <cheloha@cvs.openbsd.org>2018-05-22 19:15:23 +0000
commit708d89f83cd56f6262879af84e903cce4574143f (patch)
tree774e445bbfb9ef7b05ea489feba7d50b1f5a49fc
parent7c2e8edb17456cb4a47f595d4677b73c78f78fca (diff)
kevent: correctly check that timeout's nanoseconds are on [0, 1000000000)
Validate the input with timespecfix before truncating to a timeval. timespecfix does not round, so we need to to it by hand after validation. FreeBSD and NetBSD check the input with this range, we ought to as well. Also add a regression test for this case. ok tb@
-rw-r--r--regress/sys/kern/kqueue/Makefile6
-rw-r--r--regress/sys/kern/kqueue/kqueue-timer.c31
-rw-r--r--regress/sys/kern/kqueue/main.c7
-rw-r--r--regress/sys/kern/kqueue/main.h3
-rw-r--r--sys/kern/kern_event.c17
5 files changed, 51 insertions, 13 deletions
diff --git a/regress/sys/kern/kqueue/Makefile b/regress/sys/kern/kqueue/Makefile
index 823f6e99161..b07b46eaffe 100644
--- a/regress/sys/kern/kqueue/Makefile
+++ b/regress/sys/kern/kqueue/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.19 2016/09/20 23:05:27 bluhm Exp $
+# $OpenBSD: Makefile,v 1.20 2018/05/22 19:15:22 cheloha Exp $
PROG= kqueue-test
CFLAGS+=-Wall
@@ -32,9 +32,11 @@ kq-flock: ${PROG}
./${PROG} -l
kq-timer: ${PROG}
./${PROG} -i
+kq-invalid-timer: ${PROG}
+ ./${PROG} -I
REGRESS_TARGETS=kq-pipe kq-fork kq-process kq-random kq-pty kq-signal \
- kq-fdpass kq-flock kq-timer
+ kq-fdpass kq-flock kq-timer kq-invalid-timer
# kq-tun broke at some point, apparently from a change in tun routing
REGRESS_ROOT_TARGETS=${REGRESS_TARGETS}
.PHONY: ${REGRESS_TARGETS}
diff --git a/regress/sys/kern/kqueue/kqueue-timer.c b/regress/sys/kern/kqueue/kqueue-timer.c
index 02114b5094e..e95c3ba4e52 100644
--- a/regress/sys/kern/kqueue/kqueue-timer.c
+++ b/regress/sys/kern/kqueue/kqueue-timer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kqueue-timer.c,v 1.2 2016/09/20 23:05:27 bluhm Exp $ */
+/* $OpenBSD: kqueue-timer.c,v 1.3 2018/05/22 19:15:22 cheloha Exp $ */
/*
* Copyright (c) 2015 Bret Stephen Lambert <blambert@openbsd.org>
*
@@ -20,6 +20,7 @@
#include <sys/event.h>
#include <err.h>
+#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -68,3 +69,31 @@ do_timer(void)
return (0);
}
+
+int
+do_invalid_timer(void)
+{
+ int i, kq, n;
+ struct kevent ev;
+ struct timespec invalid_ts[3] = { {-1, 0}, {0, -1}, {0, 1000000000L} };
+
+ ASS((kq = kqueue()) >= 0,
+ warn("kqueue"));
+
+ memset(&ev, 0, sizeof(ev));
+ ev.filter = EVFILT_TIMER;
+ ev.flags = EV_ADD | EV_ENABLE;
+ ev.data = 500; /* 1/2 second in ms */
+
+ n = kevent(kq, &ev, 1, NULL, 0, NULL);
+ ASSX(n != -1);
+
+ for (i = 0; i < 3; i++) {
+ n = kevent(kq, NULL, 0, &ev, 1, &invalid_ts[i]);
+ ASS(n == -1 && errno == EINVAL,
+ warn("kevent: timeout %lld %ld",
+ (long long)invalid_ts[i].tv_sec, invalid_ts[i].tv_nsec));
+ }
+
+ return (0);
+}
diff --git a/regress/sys/kern/kqueue/main.c b/regress/sys/kern/kqueue/main.c
index 78ca80adb25..2dcafeecb30 100644
--- a/regress/sys/kern/kqueue/main.c
+++ b/regress/sys/kern/kqueue/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.9 2016/09/20 23:05:27 bluhm Exp $ */
+/* $OpenBSD: main.c,v 1.10 2018/05/22 19:15:22 cheloha Exp $ */
/*
* Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain
*/
@@ -16,7 +16,7 @@ main(int argc, char **argv)
int ret, c;
ret = 0;
- while ((c = getopt(argc, argv, "fFilpPrstT")) != -1) {
+ while ((c = getopt(argc, argv, "fFiIlpPrstT")) != -1) {
switch (c) {
case 'f':
ret |= check_inheritance();
@@ -27,6 +27,9 @@ main(int argc, char **argv)
case 'i':
ret |= do_timer();
break;
+ case 'I':
+ ret |= do_invalid_timer();
+ break;
case 'l':
ret |= do_flock();
break;
diff --git a/regress/sys/kern/kqueue/main.h b/regress/sys/kern/kqueue/main.h
index 430d63cd05b..e34fd4f9a7a 100644
--- a/regress/sys/kern/kqueue/main.h
+++ b/regress/sys/kern/kqueue/main.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.h,v 1.1 2016/09/20 23:05:27 bluhm Exp $ */
+/* $OpenBSD: main.h,v 1.2 2018/05/22 19:15:22 cheloha Exp $ */
/*
* Written by Alexaner Bluhm <bluhm@openbsd.org> 2016 Public Domain
*/
@@ -18,6 +18,7 @@
int check_inheritance(void);
int do_fdpass(void);
int do_flock(void);
+int do_invalid_timer(void);
int do_pipe(void);
int do_process(void);
int do_pty(void);
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index dd5cb18d748..f306a33e669 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.88 2018/04/27 10:13:37 mpi Exp $ */
+/* $OpenBSD: kern_event.c,v 1.89 2018/05/22 19:15:22 cheloha Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -693,6 +693,7 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *ulistp,
const struct timespec *tsp, struct proc *p, int *retval)
{
struct kevent *kevp;
+ struct timespec ats;
struct timeval atv, rtv, ttv;
struct knote *kn, marker;
int s, count, timeout, nkev = 0, error = 0;
@@ -703,16 +704,18 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *ulistp,
goto done;
if (tsp != NULL) {
- TIMESPEC_TO_TIMEVAL(&atv, tsp);
- if (tsp->tv_sec == 0 && tsp->tv_nsec == 0) {
+ ats = *tsp;
+ if (ats.tv_sec > 100000000 || timespecfix(&ats)) {
+ error = EINVAL;
+ goto done;
+ }
+ TIMESPEC_TO_TIMEVAL(&atv, &ats);
+ if (atv.tv_sec == 0 && atv.tv_usec == 0) {
/* No timeout, just poll */
timeout = -1;
goto start;
}
- if (itimerfix(&atv)) {
- error = EINVAL;
- goto done;
- }
+ itimerround(&atv);
timeout = atv.tv_sec > 24 * 60 * 60 ?
24 * 60 * 60 * hz : tvtohz(&atv);