diff options
author | 2018-05-28 09:04:44 +0000 | |
---|---|---|
committer | 2018-05-28 09:04:44 +0000 | |
commit | 6a044236e2c52f23e4de25e1184c674dd1211a01 (patch) | |
tree | 9da71f8c15cffa0cbab2c4048f1c3708ef3e51e8 | |
parent | Add clock support for i.MX8MQ. Most of the clocks can be configured (diff) | |
download | wireguard-openbsd-6a044236e2c52f23e4de25e1184c674dd1211a01.tar.xz wireguard-openbsd-6a044236e2c52f23e4de25e1184c674dd1211a01.zip |
Regress for the dup2(2) vs accept(2) race.
Note that you need a new kernel otherwise this test will make your
machine panic!
-rw-r--r-- | regress/sys/kern/Makefile | 5 | ||||
-rw-r--r-- | regress/sys/kern/dup2_accept/Makefile | 10 | ||||
-rw-r--r-- | regress/sys/kern/dup2_accept/dup2_accept.c | 99 |
3 files changed, 112 insertions, 2 deletions
diff --git a/regress/sys/kern/Makefile b/regress/sys/kern/Makefile index 70077bf101e..0d0a08d69f8 100644 --- a/regress/sys/kern/Makefile +++ b/regress/sys/kern/Makefile @@ -1,6 +1,7 @@ -# $OpenBSD: Makefile,v 1.70 2017/07/07 23:15:27 bluhm Exp $ +# $OpenBSD: Makefile,v 1.71 2018/05/28 09:04:44 mpi Exp $ -SUBDIR+= __syscall access accept dup2 dup2_self exec_self execve exit extent +SUBDIR+= __syscall access accept dup2 dup2_accept dup2_self +SUBDIR+= exec_self execve exit extent SUBDIR+= fchdir SUBDIR+= fcntl_dup SUBDIR+= flock diff --git a/regress/sys/kern/dup2_accept/Makefile b/regress/sys/kern/dup2_accept/Makefile new file mode 100644 index 00000000000..80d56efa22a --- /dev/null +++ b/regress/sys/kern/dup2_accept/Makefile @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile,v 1.1 2018/05/28 09:04:44 mpi Exp $ + +PROG= dup2_accept + +LIBPTHREAD= /usr/lib/libpthread.a + +LDADD+= -lpthread +DPADD+= ${LIBPTHREAD} + +.include <bsd.regress.mk> diff --git a/regress/sys/kern/dup2_accept/dup2_accept.c b/regress/sys/kern/dup2_accept/dup2_accept.c new file mode 100644 index 00000000000..102d2975ef6 --- /dev/null +++ b/regress/sys/kern/dup2_accept/dup2_accept.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 Martin Pieuchot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/socket.h> +#include <netinet/in.h> + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <pthread.h> +#include <string.h> +#include <unistd.h> + +#include <stdlib.h> + +/* + * Listen on localhost:TEST_PORT for a connection + */ +#define TEST_PORT 9876 + +static void * +dupper(void *arg) +{ + struct sockaddr_in addr; + int s; + + sleep(1); + + s = socket(PF_INET, SOCK_STREAM, 0); + if (s == -1) + err(1, "socket"); + + assert(s == 5); + + /* + * Make sure that dup'ing a LARVAL file fails with EBUSY. + * + * Otherwise abort the program before calling connect(2), + * this was previously panic'ing the kernel. + */ + if ((dup2(0, 4) != 4) && (errno != EBUSY)) + err(1, "dup2"); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(TEST_PORT); + + if (connect(5, (struct sockaddr *)&addr, sizeof(addr)) == -1) + err(1, "connect"); + + return NULL; +} + +int +main(void) +{ + struct sockaddr_in serv_addr; + struct sockaddr client_addr; + int error, s, len, fd; + pthread_t tr; + + if ((error = pthread_create(&tr, NULL, dupper, NULL))) + errc(1, error, "pthread_create"); + + s = socket(PF_INET, SOCK_STREAM, 0); + if (s == -1) + err(1, "socket"); + + assert(s == 3); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + serv_addr.sin_port = htons(TEST_PORT); + + if (bind(s, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) + err(1, "bind"); + + if (listen(s, 3)) + err(1, "listen"); + + len = sizeof(client_addr); + fd = accept(s, &client_addr, &len); + + return 0; +} |