diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -52,6 +52,8 @@ # xargs -n1 | sort | uniq -d; # done +# 20220624: unix_passfd_test -> unix_passfd_stream/unix_passfd_dgram +OLD_FILES+=usr/tests/sys/kern/unix_passfd_test # 20220621: ISA sound card drivers removed OLD_FILES+=usr/share/man/man4/snd_ad1816.4 diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -37,8 +37,10 @@ ATF_TESTS_C+= sysctl_kern_proc ATF_TESTS_C+= sys_getrandom ATF_TESTS_C+= unix_dgram -ATF_TESTS_C+= unix_passfd_test -TEST_METADATA.unix_passfd_test+= is_exclusive="true" +ATF_TESTS_C+= unix_passfd_dgram +TEST_METADATA.unix_passfd_dgram+= is_exclusive="true" +ATF_TESTS_C+= unix_passfd_stream +TEST_METADATA.unix_passfd_stream+= is_exclusive="true" ATF_TESTS_C+= unix_seqpacket_test TEST_METADATA.unix_seqpacket_test+= timeout="15" ATF_TESTS_C+= unix_socketpair_test diff --git a/tests/sys/kern/unix_passfd_dgram.c b/tests/sys/kern/unix_passfd_dgram.c new file mode 100644 --- /dev/null +++ b/tests/sys/kern/unix_passfd_dgram.c @@ -0,0 +1,2 @@ +#define TEST_PROTO SOCK_DGRAM +#include "unix_passfd_test.c" diff --git a/tests/sys/kern/unix_passfd_stream.c b/tests/sys/kern/unix_passfd_stream.c new file mode 100644 --- /dev/null +++ b/tests/sys/kern/unix_passfd_stream.c @@ -0,0 +1,2 @@ +#define TEST_PROTO SOCK_STREAM +#include "unix_passfd_test.c" diff --git a/tests/sys/kern/unix_passfd_test.c b/tests/sys/kern/unix_passfd_test.c --- a/tests/sys/kern/unix_passfd_test.c +++ b/tests/sys/kern/unix_passfd_test.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2005 Robert N. M. Watson * Copyright (c) 2015 Mark Johnston + * Copyright (c) 2022 Gleb Smirnoff * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,6 +47,10 @@ #include +#if !defined(TEST_PROTO) +#error Need TEST_PROTO defined to SOCK_STREAM or SOCK_DGRAM +#endif + /* * UNIX domain sockets allow file descriptors to be passed via "ancillary * data", or control messages. This regression test is intended to exercise @@ -59,8 +64,8 @@ domainsocketpair(int *fdp) { - ATF_REQUIRE_MSG(socketpair(PF_UNIX, SOCK_STREAM, 0, fdp) != -1, - "socketpair(PF_UNIX, SOCK_STREAM) failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(socketpair(PF_UNIX, TEST_PROTO, 0, fdp) != -1, + "socketpair(PF_UNIX, %u) failed: %s", TEST_PROTO, strerror(errno)); } static void @@ -153,13 +158,12 @@ ATF_REQUIRE_MSG(sb1->st_ino == sb2->st_ino, "different inode"); } -static size_t +static ssize_t sendfd_payload(int sockfd, int send_fd, void *payload, size_t paylen) { struct iovec iovec; char message[CMSG_SPACE(sizeof(int))]; struct msghdr msghdr; - ssize_t len; bzero(&msghdr, sizeof(msghdr)); bzero(&message, sizeof(message)); @@ -174,9 +178,7 @@ msghdr.msg_iovlen = 1; putfds(message, send_fd, 1); - len = sendmsg(sockfd, &msghdr, 0); - ATF_REQUIRE_MSG(len != -1, "sendmsg failed: %s", strerror(errno)); - return ((size_t)len); + return (sendmsg(sockfd, &msghdr, 0)); } static void @@ -253,6 +255,9 @@ "recvmsg: did not receive single-fd message"); ATF_REQUIRE_MSG(!localcreds(sockfd) || foundcreds, "recvmsg: expected credentials were not received"); + if (recvmsg_flags & MSG_TRUNC) + ATF_REQUIRE_MSG(msghdr.msg_flags & MSG_TRUNC, + "recvmsg: expected MSG_TRUNC missing"); } static void @@ -426,13 +431,25 @@ /* Such attempt shall fail with EMSGSIZE. */ ATF_REQUIRE(errno == EMSGSIZE); ATF_REQUIRE(getnfds() == nfds); +#if TEST_PROTO == SOCK_STREAM /* * For the SOCK_STREAM the above attempt shall free the control in * the kernel, so that socket isn't left in a stuck state. Next read - * shall bring us the normal data only. + * shall bring us the normal data only. The stream data shall not + * miss a byte. */ ATF_REQUIRE(recvmsg(fd[1], &msghdr, 0) == 1); ATF_REQUIRE(msghdr.msg_controllen == 0); +#elif TEST_PROTO == SOCK_DGRAM + /* + * For SOCK_DGRAM there are two options for the previously failed + * syscall: strip the control leaving datagram in the socket or + * drop the whole datagram. Our implementation drops the whole + * datagram. + */ + ATF_REQUIRE(recvmsg(fd[1], &msghdr, MSG_DONTWAIT) == -1); + ATF_REQUIRE(errno == EAGAIN); +#endif } /* @@ -514,7 +531,11 @@ closesocketpair(fd); } +#if TEST_PROTO == SOCK_STREAM #define LOCAL_SENDSPACE_SYSCTL "net.local.stream.sendspace" +#elif TEST_PROTO == SOCK_DGRAM +#define LOCAL_SENDSPACE_SYSCTL "net.local.dgram.maxdgram" +#endif /* * Test for PR 181741. Receiver sets LOCAL_CREDS, and kernel prepends a @@ -527,7 +548,7 @@ { const int on = 1; u_long sendspace; - size_t len; + ssize_t len; void *buf; int fd[2], getfd, putfd, rc; @@ -551,9 +572,21 @@ strerror(errno)); len = sendfd_payload(fd[0], putfd, buf, sendspace); - ATF_REQUIRE_MSG(len < sendspace, "sendmsg: %zu bytes sent", len); +#if TEST_PROTO == SOCK_STREAM + ATF_REQUIRE_MSG(len != -1 , "sendmsg failed: %s", strerror(errno)); + ATF_REQUIRE_MSG((size_t)len < sendspace, + "sendmsg: %zu bytes sent", len); recvfd_payload(fd[1], &getfd, buf, len, CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + CMSG_SPACE(sizeof(int)), 0); +#endif +#if TEST_PROTO == SOCK_DGRAM + ATF_REQUIRE_MSG(len != -1 , "sendmsg failed: %s", strerror(errno)); + ATF_REQUIRE_MSG((size_t)len == sendspace, + "sendmsg: %zu bytes sent", len); + recvfd_payload(fd[1], &getfd, buf, len, + CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + CMSG_SPACE(sizeof(int)), + MSG_TRUNC); +#endif close(putfd); close(getfd); @@ -719,7 +752,8 @@ devnull(&putfd); nfds = getnfds(); - sendfd_payload(fd[0], putfd, buf, sizeof(buf)); + len = sendfd_payload(fd[0], putfd, buf, sizeof(buf)); + ATF_REQUIRE_MSG(len != -1, "sendmsg failed: %s", strerror(errno)); bzero(&msghdr, sizeof(msghdr));