aboutsummaryrefslogtreecommitdiff
path: root/tests/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sys/kern')
-rw-r--r--tests/sys/kern/socket_accf.c32
-rw-r--r--tests/sys/kern/unix_passfd_test.c29
-rw-r--r--tests/sys/kern/unix_seqpacket_test.c62
-rw-r--r--tests/sys/kern/unix_stream.c51
4 files changed, 163 insertions, 11 deletions
diff --git a/tests/sys/kern/socket_accf.c b/tests/sys/kern/socket_accf.c
index ae6522397cf7..939ca9495689 100644
--- a/tests/sys/kern/socket_accf.c
+++ b/tests/sys/kern/socket_accf.c
@@ -69,14 +69,8 @@ clientsock(struct sockaddr_in *sin)
static void
accfon(int l, struct accept_filter_arg *af)
{
-
if (setsockopt(l, SOL_SOCKET, SO_ACCEPTFILTER, af, sizeof(*af)) != 0) {
- if (errno == ENOENT)
- atf_tc_skip("Accept filter %s not loaded in kernel",
- af->af_name);
- else
- atf_tc_fail("setsockopt(SO_ACCEPTFILTER): %s",
- strerror(errno));
+ atf_tc_fail("setsockopt(SO_ACCEPTFILTER): %s", strerror(errno));
}
}
@@ -95,7 +89,11 @@ usend(int s, const void *msg, size_t len)
return (rv);
}
-ATF_TC_WITHOUT_HEAD(data);
+ATF_TC(data);
+ATF_TC_HEAD(data, tc)
+{
+ atf_tc_set_md_var(tc, "require.kmods", "accf_data");
+}
ATF_TC_BODY(data, tc)
{
struct accept_filter_arg afa = {
@@ -113,7 +111,11 @@ ATF_TC_BODY(data, tc)
ATF_REQUIRE((a = accept(l, NULL, 0)) > 0);
}
-ATF_TC_WITHOUT_HEAD(http);
+ATF_TC(http);
+ATF_TC_HEAD(http, tc)
+{
+ atf_tc_set_md_var(tc, "require.kmods", "accf_http");
+}
ATF_TC_BODY(http, tc)
{
struct accept_filter_arg afa = {
@@ -152,7 +154,11 @@ ATF_TC_BODY(http, tc)
ATF_REQUIRE((a = accept(l, NULL, 0)) > 0);
}
-ATF_TC_WITHOUT_HEAD(tls);
+ATF_TC(tls);
+ATF_TC_HEAD(tls, tc)
+{
+ atf_tc_set_md_var(tc, "require.kmods", "accf_tls");
+}
ATF_TC_BODY(tls, tc)
{
struct accept_filter_arg afa = {
@@ -210,7 +216,11 @@ ATF_TC_BODY(tls, tc)
}
/* Check changing to a different filter. */
-ATF_TC_WITHOUT_HEAD(change);
+ATF_TC(change);
+ATF_TC_HEAD(change, tc)
+{
+ atf_tc_set_md_var(tc, "require.kmods", "accf_data accf_http");
+}
ATF_TC_BODY(change, tc)
{
struct accept_filter_arg dfa = {
diff --git a/tests/sys/kern/unix_passfd_test.c b/tests/sys/kern/unix_passfd_test.c
index 7dc4541ad402..66bb406ea14e 100644
--- a/tests/sys/kern/unix_passfd_test.c
+++ b/tests/sys/kern/unix_passfd_test.c
@@ -1189,6 +1189,34 @@ ATF_TC_CLEANUP(cross_jail_dirfd, tc)
err(1, "jail_remove");
}
+ATF_TC_WITHOUT_HEAD(listening_socket);
+ATF_TC_BODY(listening_socket, tc)
+{
+ struct sockaddr_un sun;
+ int error, ls, s[2];
+
+ ls = socket(AF_UNIX, SOCK_STREAM, 0);
+ ATF_REQUIRE(ls != -1);
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_len = sizeof(sun);
+ sun.sun_family = AF_UNIX;
+ snprintf(sun.sun_path, sizeof(sun.sun_path), "listen.sock");
+ error = bind(ls, (struct sockaddr *)&sun, sizeof(sun));
+ ATF_REQUIRE_MSG(error == 0, "bind failed: %s", strerror(errno));
+ error = listen(ls, 0);
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, s);
+ ATF_REQUIRE_MSG(error == 0, "socketpair failed: %s", strerror(errno));
+
+ sendfd(s[0], ls);
+ sendfd(s[0], s[0]);
+ sendfd(s[0], s[1]);
+ close(ls);
+ close(s[0]);
+ close(s[1]);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -1211,6 +1239,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, empty_rights_message);
ATF_TP_ADD_TC(tp, control_creates_records);
ATF_TP_ADD_TC(tp, cross_jail_dirfd);
+ ATF_TP_ADD_TC(tp, listening_socket);
return (atf_no_error());
}
diff --git a/tests/sys/kern/unix_seqpacket_test.c b/tests/sys/kern/unix_seqpacket_test.c
index b9a6be015241..27bd430430b4 100644
--- a/tests/sys/kern/unix_seqpacket_test.c
+++ b/tests/sys/kern/unix_seqpacket_test.c
@@ -1314,6 +1314,67 @@ ATF_TC_BODY(random_eor_and_waitall, tc)
free(params.records);
}
+/* See bug 290658. */
+#define PEEK_RACE_SIZE 10
+#define PEEK_RACE_TRIES 10000
+static void *
+peek_race_writer(void *args)
+{
+ struct timespec ts = {};
+ u_short seed[3];
+ char buf[PEEK_RACE_SIZE];
+ int fd = *(int *)args;
+
+ arc4random_buf(seed, sizeof(seed));
+ for (u_int i = 0; i < PEEK_RACE_TRIES; i++) {
+ ATF_REQUIRE_EQ(PEEK_RACE_SIZE,
+ send(fd, buf, sizeof(buf), MSG_EOR));
+ ts.tv_nsec = nrand48(seed) % 20;
+ (void)clock_nanosleep(CLOCK_MONOTONIC_FAST, 0, &ts, NULL);
+ }
+
+ return (NULL);
+}
+
+static void *
+peek_race_peeker(void *args)
+{
+ char buf[PEEK_RACE_SIZE * 10];
+ int fd = *(int *)args;
+
+ for (u_int i = 0; i < PEEK_RACE_TRIES; i++) {
+ ssize_t rcvd;
+
+ while ((rcvd = recv(fd, buf, sizeof(buf),
+ MSG_PEEK | MSG_DONTWAIT)) == -1)
+ ATF_REQUIRE(errno == EAGAIN);
+ ATF_REQUIRE(rcvd == PEEK_RACE_SIZE);
+
+ ATF_REQUIRE_EQ(PEEK_RACE_SIZE,
+ recv(fd, buf, sizeof(buf), 0));
+ }
+
+ return (NULL);
+}
+
+ATF_TC_WITHOUT_HEAD(peek_race);
+ATF_TC_BODY(peek_race, tc)
+{
+ pthread_t peeker, writer;
+ int sv[2];
+
+ do_socketpair(sv);
+
+ ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, peek_race_writer,
+ &sv[0]));
+ ATF_REQUIRE_EQ(0, pthread_create(&peeker, NULL, peek_race_peeker,
+ &sv[1]));
+ ATF_REQUIRE_EQ(0, pthread_join(writer, NULL));
+ ATF_REQUIRE_EQ(0, pthread_join(peeker, NULL));
+ close(sv[0]);
+ close(sv[1]);
+}
+
/*
* Main.
*/
@@ -1370,6 +1431,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, pipe_128k_8k);
ATF_TP_ADD_TC(tp, pipe_128k_128k);
ATF_TP_ADD_TC(tp, random_eor_and_waitall);
+ ATF_TP_ADD_TC(tp, peek_race);
return atf_no_error();
}
diff --git a/tests/sys/kern/unix_stream.c b/tests/sys/kern/unix_stream.c
index bb811f78f620..442b766ac885 100644
--- a/tests/sys/kern/unix_stream.c
+++ b/tests/sys/kern/unix_stream.c
@@ -1,6 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
+ * Copyright (c) 2025 Gleb Smirnoff <glebius@FreeBSD.org>
* Copyright (c) 2018 Alan Somers
*
* Redistribution and use in source and binary forms, with or without
@@ -30,6 +31,7 @@
#include <sys/event.h>
#include <sys/select.h>
#include <sys/sysctl.h>
+#include <sys/time.h>
#include <sys/un.h>
#include <errno.h>
#include <fcntl.h>
@@ -467,6 +469,53 @@ ATF_TC_BODY(peershutdown_wakeup_kevent, tc)
});
}
+ATF_TC_WITHOUT_HEAD(ourshutdown_kevent);
+ATF_TC_BODY(ourshutdown_kevent, tc)
+{
+ struct kevent kev;
+ int sv[2], kq;
+
+ do_socketpair(sv);
+ ATF_REQUIRE(kq = kqueue());
+
+ EV_SET(&kev, sv[1], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
+ ATF_REQUIRE(kevent(kq, &kev, 1, NULL, 0, NULL) == 0);
+
+ ATF_REQUIRE(shutdown(sv[1], SHUT_WR) == 0);
+
+ ATF_REQUIRE(kevent(kq, NULL, 0, &kev, 1, NULL) == 1);
+ ATF_REQUIRE(kev.ident == (uintptr_t)sv[1] &&
+ kev.filter == EVFILT_WRITE &&
+ kev.flags == EV_EOF);
+
+ close(sv[0]);
+ close(sv[1]);
+}
+
+ATF_TC_WITHOUT_HEAD(SO_SNDTIMEO);
+ATF_TC_BODY(SO_SNDTIMEO, tc)
+{
+ struct timespec tp1, tp2, rtp, sleep = { .tv_nsec = 100000000 };
+ int sv[2];
+ char buf[10];
+
+ full_socketpair(sv);
+ ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDTIMEO,
+ &(struct timeval){ .tv_usec = sleep.tv_nsec / 1000 },
+ sizeof(struct timeval)));
+ ATF_REQUIRE_EQ(0, clock_gettime(CLOCK_MONOTONIC_PRECISE, &tp1));
+ ATF_REQUIRE_EQ(-1, send(sv[0], buf, sizeof(buf), 0));
+ ATF_REQUIRE(errno == EAGAIN);
+ ATF_REQUIRE_EQ(0, clock_gettime(CLOCK_MONOTONIC_PRECISE, &tp2));
+ timespecsub(&tp2, &tp1, &rtp);
+ ATF_REQUIRE(timespeccmp(&rtp, &sleep, >=));
+ ATF_REQUIRE_EQ(sizeof(buf), recv(sv[1], buf, sizeof(buf), 0));
+ ATF_REQUIRE_EQ(sizeof(buf), send(sv[0], buf, sizeof(buf), 0));
+
+ close(sv[0]);
+ close(sv[1]);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, getpeereid);
@@ -482,6 +531,8 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, peershutdown_wakeup_select);
ATF_TP_ADD_TC(tp, peershutdown_wakeup_poll);
ATF_TP_ADD_TC(tp, peershutdown_wakeup_kevent);
+ ATF_TP_ADD_TC(tp, ourshutdown_kevent);
+ ATF_TP_ADD_TC(tp, SO_SNDTIMEO);
return atf_no_error();
}