From de793022e14e2f8cc967b50894e9368ffeb86115 Mon Sep 17 00:00:00 2001 From: mvs Date: Fri, 19 Nov 2021 17:14:38 +0000 Subject: [PATCH] Add and enable the new 'undgram_conclose' test which tries to kill the datagram socket connected to the dying socket while it cleaning it's list of connected sockets. Incorrect handling of this case could produce kernel crash. ok bluhm@ --- regress/sys/kern/Makefile | 6 +- regress/sys/kern/undgram_conclose/Makefile | 22 +++ .../kern/undgram_conclose/undgram_conclose.c | 144 ++++++++++++++++++ 3 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 regress/sys/kern/undgram_conclose/Makefile create mode 100644 regress/sys/kern/undgram_conclose/undgram_conclose.c diff --git a/regress/sys/kern/Makefile b/regress/sys/kern/Makefile index e75259ce3cd..3df716ed91a 100644 --- a/regress/sys/kern/Makefile +++ b/regress/sys/kern/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.92 2021/11/19 17:07:10 mvs Exp $ +# $OpenBSD: Makefile,v 1.93 2021/11/19 17:14:38 mvs Exp $ SUBDIR+= __syscall SUBDIR+= accept access @@ -22,8 +22,8 @@ SUBDIR+= setuid .endif SUBDIR+= signal sosplice stackjmp stackpivot syscall syscall_segment SUBDIR+= sysvmsg sysvsem sysvshm -SUBDIR+= unalign unfdpass unfdpassfail ungc unsendrecvthr unixsock unveil -SUBDIR+= unveil-unmount +SUBDIR+= unalign undgram_conclose unfdpass unfdpassfail ungc unsendrecvthr +SUBDIR+= unixsock unveil unveil-unmount SUBDIR+= wait install: diff --git a/regress/sys/kern/undgram_conclose/Makefile b/regress/sys/kern/undgram_conclose/Makefile new file mode 100644 index 00000000000..e306448671b --- /dev/null +++ b/regress/sys/kern/undgram_conclose/Makefile @@ -0,0 +1,22 @@ +# $OpenBSD: Makefile,v 1.1 2021/11/19 17:14:38 mvs Exp $ + +# Copyright (c) 2021 Makkoveev Vitaliy +# +# 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. + +WARNINGS = yes + +PROG = undgram_conclose +LDADD+= -lpthread + +.include diff --git a/regress/sys/kern/undgram_conclose/undgram_conclose.c b/regress/sys/kern/undgram_conclose/undgram_conclose.c new file mode 100644 index 00000000000..cf0ceaf0166 --- /dev/null +++ b/regress/sys/kern/undgram_conclose/undgram_conclose.c @@ -0,0 +1,144 @@ +/* $OpenBSD: undgram_conclose.c,v 1.1 2021/11/19 17:14:38 mvs Exp $ */ + +/* + * Copyright (c) 2021 Vitaliy Makkoveev + * + * 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. + */ + +/* + * Try to kill the datagram socket connected to the dying socket while + * it cleaning it's list of connected sockets. Incorrect handling of + * this case could produce kernel crash. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pthread_mutex_t therr_mtx = PTHREAD_MUTEX_INITIALIZER; + +static void +therr(int eval, const char *fmt, ...) +{ + va_list ap; + + pthread_mutex_lock(&therr_mtx); + + va_start(ap, fmt); + verr(eval, fmt, ap); + va_end(ap); +} + +static void +therrc(int eval, int code, const char *fmt, ...) +{ + va_list ap; + + pthread_mutex_lock(&therr_mtx); + + va_start(ap, fmt); + verrc(eval, code, fmt, ap); + va_end(ap); +} + +static void * +thr_close(void *arg) +{ + struct sockaddr_un *sun = arg; + int s; + + while (1) { + unlink(sun->sun_path); + + if ((s = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) + therr(1, "socket"); + if (bind(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) + therr(1, "bind"); + close(s); + } + + return NULL; +} + +static void * +thr_conn(void *arg) +{ + struct sockaddr_un *sun = arg; + int s; + + while (1) { + if ((s = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) + therr(1, "socket"); + connect(s, (struct sockaddr *)sun, sizeof(*sun)); + close(s); + } + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + struct timeval testtime = { + .tv_sec = 60, + .tv_usec = 0, + }; + struct timeval *tv = &testtime; + + int mib[2], ncpu; + size_t len; + + struct sockaddr_un sun; + + pthread_t thr; + int error, i; + + if (argc == 2 && !strcmp(argv[1], "--infinite")) + tv = NULL; + + mib[0] = CTL_HW; + mib[1] = HW_NCPUONLINE; + len = sizeof(ncpu); + + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) < 0) + err(1, "sysctl"); + if (ncpu <= 0) + errx(1, "Wrong number of CPUs online: %d", ncpu); + + memset(&sun, 0, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + snprintf(sun.sun_path, sizeof(sun.sun_path) - 1, + "/tmp/socket%d", getpid()); + + if ((error = pthread_create(&thr, NULL, thr_close, &sun))) + therrc(1, error, "pthread_create"); + + for (i = 0; i < (ncpu * 4); ++i) { + if ((error = pthread_create(&thr, NULL, thr_conn, &sun))) + therrc(1, error, "pthread_create"); + } + + select(0, NULL, NULL, NULL, tv); + + return 0; +} -- 2.20.1