diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2018-08-24 12:46:40 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2018-08-24 12:46:40 +0000 |
commit | 9dd4c82997dde3f28fe1cf175381d4bb4f3600a9 (patch) | |
tree | bf3eb21d4641e7d2bd807a28853f82022630d417 | |
parent | 40cdefb1095e3a14eea7552a1c6125e2736b4c99 (diff) |
Add a regression test for the kernel stack exhaustion bug.
OK anton@
-rw-r--r-- | regress/sys/kern/kqueue/Makefile | 7 | ||||
-rw-r--r-- | regress/sys/kern/kqueue/kqueue-regress.c | 65 |
2 files changed, 69 insertions, 3 deletions
diff --git a/regress/sys/kern/kqueue/Makefile b/regress/sys/kern/kqueue/Makefile index b2d2a838447..f53c3c7f2fb 100644 --- a/regress/sys/kern/kqueue/Makefile +++ b/regress/sys/kern/kqueue/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.22 2018/08/13 06:36:29 anton Exp $ +# $OpenBSD: Makefile,v 1.23 2018/08/24 12:46:39 visa Exp $ PROG= kqueue-test CFLAGS+=-Wall @@ -38,9 +38,12 @@ kq-regress-1: ${PROG} ./${PROG} -R1 kq-regress-2: ${PROG} ./${PROG} -R2 +kq-regress-3: ${PROG} + ./${PROG} -R3 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-1 kq-regress-2 + kq-fdpass kq-flock kq-timer kq-invalid-timer kq-regress-1 \ + kq-regress-2 kq-regress-3 # 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-regress.c b/regress/sys/kern/kqueue/kqueue-regress.c index f699b20e9df..bd6f578868f 100644 --- a/regress/sys/kern/kqueue/kqueue-regress.c +++ b/regress/sys/kern/kqueue/kqueue-regress.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kqueue-regress.c,v 1.2 2018/08/13 06:36:29 anton Exp $ */ +/* $OpenBSD: kqueue-regress.c,v 1.3 2018/08/24 12:46:39 visa Exp $ */ /* * Written by Anton Lindqvist <anton@openbsd.org> 2018 Public Domain */ @@ -18,6 +18,9 @@ static int do_regress1(void); static int do_regress2(void); +static int do_regress3(void); + +static void make_chain(int); int do_regress(int n) @@ -27,6 +30,8 @@ do_regress(int n) return do_regress1(); case 2: return do_regress2(); + case 3: + return do_regress3(); default: errx(1, "unknown regress test number %d", n); } @@ -106,3 +111,61 @@ do_regress2(void) return 0; } + +/* + * Regression test for kernel stack exhaustion. + */ +static int +do_regress3(void) +{ + pid_t pid; + int dir, status; + + for (dir = 0; dir < 2; dir++) { + pid = fork(); + if (pid == -1) + err(1, "fork"); + + if (pid == 0) { + make_chain(dir); + _exit(0); + } + + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + assert(WIFEXITED(status)); + assert(WEXITSTATUS(status) == 0); + } + + return 0; +} + +static void +make_chain(int dir) +{ + struct kevent kev[1]; + int i, kq, prev; + + /* + * Build a chain of kqueues and leave the files open. + * If the chain is long enough and properly oriented, a broken kernel + * can exhaust the stack when this process exits. + */ + for (i = 0, prev = -1; i < 120; i++, prev = kq) { + kq = kqueue(); + if (kq == -1) + err(1, "kqueue"); + if (prev == -1) + continue; + + if (dir == 0) { + EV_SET(&kev[0], prev, EVFILT_READ, EV_ADD, 0, 0, NULL); + if (kevent(kq, kev, 1, NULL, 0, NULL) == -1) + err(1, "kevent"); + } else { + EV_SET(&kev[0], kq, EVFILT_READ, EV_ADD, 0, 0, NULL); + if (kevent(prev, kev, 1, NULL, 0, NULL) == -1) + err(1, "kevent"); + } + } +} |