-# $OpenBSD: Makefile,v 1.21 2018/06/17 08:30:20 anton Exp $
+# $OpenBSD: Makefile,v 1.22 2018/08/13 06:36:29 anton Exp $
PROG= kqueue-test
CFLAGS+=-Wall
./${PROG} -i
kq-invalid-timer: ${PROG}
./${PROG} -I
-kq-regress: ${PROG}
- ./${PROG} -R
+kq-regress-1: ${PROG}
+ ./${PROG} -R1
+kq-regress-2: ${PROG}
+ ./${PROG} -R2
REGRESS_TARGETS=kq-pipe kq-fork kq-process kq-random kq-pty kq-signal \
- kq-fdpass kq-flock kq-timer kq-invalid-timer kq-regress
+ kq-fdpass kq-flock kq-timer kq-invalid-timer kq-regress-1 kq-regress-2
# kq-tun broke at some point, apparently from a change in tun routing
REGRESS_ROOT_TARGETS=${REGRESS_TARGETS}
.PHONY: ${REGRESS_TARGETS}
-/* $OpenBSD: kqueue-regress.c,v 1.1 2018/06/17 08:30:20 anton Exp $ */
+/* $OpenBSD: kqueue-regress.c,v 1.2 2018/08/13 06:36:29 anton Exp $ */
/*
* Written by Anton Lindqvist <anton@openbsd.org> 2018 Public Domain
*/
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
+#include <sys/wait.h>
+#include <assert.h>
#include <err.h>
#include <signal.h>
#include <stdlib.h>
+#include <unistd.h>
#include "main.h"
+static int do_regress1(void);
+static int do_regress2(void);
+
int
-do_regress(void)
+do_regress(int n)
+{
+ switch (n) {
+ case 1:
+ return do_regress1();
+ case 2:
+ return do_regress2();
+ default:
+ errx(1, "unknown regress test number %d", n);
+ }
+}
+
+/*
+ * Regression test for NULL-deref in knote_processexit().
+ */
+static int
+do_regress1(void)
{
struct kevent kev[2];
int kq;
return 0;
}
+
+/*
+ * Regression test for use-after-free in kqueue_close().
+ */
+static int
+do_regress2(void)
+{
+ pid_t pid;
+ int i, status;
+
+ /* Run twice in order to trigger the panic faster, if still present. */
+ for (i = 0; i < 2; i++) {
+ pid = fork();
+ if (pid == -1)
+ err(1, "fork");
+
+ if (pid == 0) {
+ struct kevent kev[1];
+ int p0[2], p1[2];
+ int kq;
+
+ if (pipe(p0) == -1)
+ err(1, "pipe");
+ if (pipe(p1) == -1)
+ err(1, "pipe");
+
+ kq = kqueue();
+ if (kq == -1)
+ err(1, "kqueue");
+
+ EV_SET(&kev[0], p0[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
+ if (kevent(kq, kev, 1, NULL, 0, NULL) == -1)
+ err(1, "kevent");
+
+ EV_SET(&kev[0], p1[1], EVFILT_READ, EV_ADD, 0, 0, NULL);
+ if (kevent(kq, kev, 1, NULL, 0, NULL) == -1)
+ err(1, "kevent");
+
+ EV_SET(&kev[0], p1[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
+ if (kevent(kq, kev, 1, NULL, 0, NULL) == -1)
+ err(1, "kevent");
+
+ _exit(0);
+ }
+
+ if (waitpid(pid, &status, 0) == -1)
+ err(1, "waitpid");
+ assert(WIFEXITED(status));
+ assert(WEXITSTATUS(status) == 0);
+ }
+
+ return 0;
+}
-/* $OpenBSD: main.c,v 1.12 2018/06/17 08:32:24 anton Exp $ */
+/* $OpenBSD: main.c,v 1.13 2018/08/13 06:36:29 anton Exp $ */
/*
* Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain
*/
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
main(int argc, char **argv)
{
extern char *__progname;
- int ret, c;
+ int r, ret, c;
ret = 0;
- while ((c = getopt(argc, argv, "fFiIlpPrRstT")) != -1) {
+ while ((c = getopt(argc, argv, "fFiIlpPrR:stT")) != -1) {
switch (c) {
case 'f':
ret |= check_inheritance();
ret |= do_random();
break;
case 'R':
- ret |= do_regress();
+ r = strtonum(optarg, 1, INT_MAX, NULL);
+ ret |= do_regress(r);
break;
case 's':
ret |= do_signal();
ret |= do_pty();
break;
default:
- fprintf(stderr, "usage: %s -[fFiIlpPrRstT]\n",
+ fprintf(stderr, "usage: %s -[fFiIlpPrstT] [-R n]\n",
__progname);
exit(1);
}