1*d7d962eaSAlex Richardson /*-
2*d7d962eaSAlex Richardson * SPDX-License-Identifier: BSD-2-Clause
3*d7d962eaSAlex Richardson *
4*d7d962eaSAlex Richardson * Copyright 2021 Jan Kokemüller
5*d7d962eaSAlex Richardson * Copyright 2021 Alex Richardson <arichardson@FreeBSD.org>
6*d7d962eaSAlex Richardson *
7*d7d962eaSAlex Richardson * This work was supported by Innovate UK project 105694, "Digital Security by
8*d7d962eaSAlex Richardson * Design (DSbD) Technology Platform Prototype".
9*d7d962eaSAlex Richardson *
10*d7d962eaSAlex Richardson * Redistribution and use in source and binary forms, with or without
11*d7d962eaSAlex Richardson * modification, are permitted provided that the following conditions
12*d7d962eaSAlex Richardson * are met:
13*d7d962eaSAlex Richardson * 1. Redistributions of source code must retain the above copyright
14*d7d962eaSAlex Richardson * notice, this list of conditions and the following disclaimer.
15*d7d962eaSAlex Richardson * 2. Redistributions in binary form must reproduce the above copyright
16*d7d962eaSAlex Richardson * notice, this list of conditions and the following disclaimer in the
17*d7d962eaSAlex Richardson * documentation and/or other materials provided with the distribution.
18*d7d962eaSAlex Richardson *
19*d7d962eaSAlex Richardson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20*d7d962eaSAlex Richardson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*d7d962eaSAlex Richardson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*d7d962eaSAlex Richardson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23*d7d962eaSAlex Richardson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*d7d962eaSAlex Richardson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*d7d962eaSAlex Richardson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*d7d962eaSAlex Richardson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*d7d962eaSAlex Richardson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*d7d962eaSAlex Richardson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*d7d962eaSAlex Richardson * SUCH DAMAGE.
30*d7d962eaSAlex Richardson */
31*d7d962eaSAlex Richardson #include <sys/cdefs.h>
32*d7d962eaSAlex Richardson #include <sys/event.h>
33*d7d962eaSAlex Richardson
34*d7d962eaSAlex Richardson #include <atf-c.h>
35*d7d962eaSAlex Richardson #include <errno.h>
36*d7d962eaSAlex Richardson #include <signal.h>
37*d7d962eaSAlex Richardson
38*d7d962eaSAlex Richardson ATF_TC_WITHOUT_HEAD(main);
39*d7d962eaSAlex Richardson
ATF_TC_BODY(main,tc)40*d7d962eaSAlex Richardson ATF_TC_BODY(main, tc)
41*d7d962eaSAlex Richardson {
42*d7d962eaSAlex Richardson int rv;
43*d7d962eaSAlex Richardson
44*d7d962eaSAlex Richardson sigset_t set;
45*d7d962eaSAlex Richardson rv = sigemptyset(&set);
46*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
47*d7d962eaSAlex Richardson rv = sigaddset(&set, SIGUSR1);
48*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
49*d7d962eaSAlex Richardson rv = sigprocmask(SIG_BLOCK, &set, NULL);
50*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
51*d7d962eaSAlex Richardson
52*d7d962eaSAlex Richardson int skq = kqueue();
53*d7d962eaSAlex Richardson ATF_REQUIRE(skq >= 0);
54*d7d962eaSAlex Richardson
55*d7d962eaSAlex Richardson struct kevent kev;
56*d7d962eaSAlex Richardson EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
57*d7d962eaSAlex Richardson rv = kevent(skq, &kev, 1, NULL, 0, NULL);
58*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
59*d7d962eaSAlex Richardson
60*d7d962eaSAlex Richardson int kq = kqueue();
61*d7d962eaSAlex Richardson ATF_REQUIRE(kq >= 0);
62*d7d962eaSAlex Richardson
63*d7d962eaSAlex Richardson EV_SET(&kev, skq, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0);
64*d7d962eaSAlex Richardson rv = kevent(kq, &kev, 1, NULL, 0, NULL);
65*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
66*d7d962eaSAlex Richardson
67*d7d962eaSAlex Richardson /*
68*d7d962eaSAlex Richardson * It was previously not guaranteed that sending a signal to self would
69*d7d962eaSAlex Richardson * be immediately visible in the nested kqueue activation with a zero
70*d7d962eaSAlex Richardson * timeout. As of https://reviews.freebsd.org/D31858, the kqueue task
71*d7d962eaSAlex Richardson * queue will be processed in this case, so we are guaranteed to see the
72*d7d962eaSAlex Richardson * SIGUSR1 here even with a zero timeout. We run the code below in a
73*d7d962eaSAlex Richardson * loop to make it more likely that older kernels without the fix fail
74*d7d962eaSAlex Richardson * this test.
75*d7d962eaSAlex Richardson */
76*d7d962eaSAlex Richardson for (int i = 0; i < 100; i++) {
77*d7d962eaSAlex Richardson rv = kill(getpid(), SIGUSR1);
78*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
79*d7d962eaSAlex Richardson
80*d7d962eaSAlex Richardson rv = kevent(kq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
81*d7d962eaSAlex Richardson ATF_REQUIRE_EQ_MSG(1, rv,
82*d7d962eaSAlex Richardson "Unexpected result %d from kevent() after %d iterations",
83*d7d962eaSAlex Richardson rv, i);
84*d7d962eaSAlex Richardson rv = kevent(kq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
85*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
86*d7d962eaSAlex Richardson
87*d7d962eaSAlex Richardson rv = kevent(skq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
88*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(1, rv);
89*d7d962eaSAlex Richardson rv = kevent(skq, NULL, 0, &kev, 1, &(struct timespec) { 0, 0 });
90*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(0, rv);
91*d7d962eaSAlex Richardson
92*d7d962eaSAlex Richardson siginfo_t siginfo;
93*d7d962eaSAlex Richardson rv = sigtimedwait(&set, &siginfo, &(struct timespec) { 0, 0 });
94*d7d962eaSAlex Richardson ATF_REQUIRE_EQ(SIGUSR1, rv);
95*d7d962eaSAlex Richardson
96*d7d962eaSAlex Richardson rv = sigtimedwait(&set, &siginfo, &(struct timespec) { 0, 0 });
97*d7d962eaSAlex Richardson ATF_REQUIRE_ERRNO(EAGAIN, rv < 0);
98*d7d962eaSAlex Richardson }
99*d7d962eaSAlex Richardson }
100*d7d962eaSAlex Richardson
ATF_TP_ADD_TCS(tp)101*d7d962eaSAlex Richardson ATF_TP_ADD_TCS(tp)
102*d7d962eaSAlex Richardson {
103*d7d962eaSAlex Richardson ATF_TP_ADD_TC(tp, main);
104*d7d962eaSAlex Richardson
105*d7d962eaSAlex Richardson return (atf_no_error());
106*d7d962eaSAlex Richardson }
107