git: 69d79ceb2c01 - main - tests/unix_passfd: add test case against 636420bde36
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 30 Sep 2022 20:45:05 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=69d79ceb2c01931c129c5bafc300c33f3e106efd
commit 69d79ceb2c01931c129c5bafc300c33f3e106efd
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-09-30 20:41:41 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-09-30 20:43:37 +0000
tests/unix_passfd: add test case against 636420bde36
---
tests/sys/kern/unix_passfd_test.c | 72 +++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/tests/sys/kern/unix_passfd_test.c b/tests/sys/kern/unix_passfd_test.c
index 875201c4702e..92b8d73f2f4a 100644
--- a/tests/sys/kern/unix_passfd_test.c
+++ b/tests/sys/kern/unix_passfd_test.c
@@ -270,8 +270,10 @@ recvfd(int sockfd, int *recv_fd, int flags)
#if TEST_PROTO == SOCK_STREAM
#define LOCAL_SENDSPACE_SYSCTL "net.local.stream.sendspace"
+#define LOCAL_RECVSPACE_SYSCTL "net.local.stream.recvspace"
#elif TEST_PROTO == SOCK_DGRAM
#define LOCAL_SENDSPACE_SYSCTL "net.local.dgram.maxdgram"
+#define LOCAL_RECVSPACE_SYSCTL "net.local.dgram.recvspace"
#endif
static u_long
@@ -286,6 +288,46 @@ getsendspace(void)
return (sendspace);
}
+static u_long
+getrecvspace(void)
+{
+ u_long recvspace;
+
+ ATF_REQUIRE_MSG(sysctlbyname(LOCAL_RECVSPACE_SYSCTL, &recvspace,
+ &(size_t){sizeof(u_long)}, NULL, 0) != -1,
+ "sysctl %s failed: %s", LOCAL_RECVSPACE_SYSCTL, strerror(errno));
+
+ return (recvspace);
+}
+
+/*
+ * Fill socket to a state when next max sized send would fail with EAGAIN.
+ */
+static void
+fill(int fd)
+{
+ u_long sendspace;
+ void *buf;
+
+ sendspace = getsendspace();
+ ATF_REQUIRE((buf = malloc(sendspace)) != NULL);
+
+ ATF_REQUIRE_MSG(fcntl(fd, F_SETFL, O_NONBLOCK) != -1,
+ "fcntl(O_NONBLOCK) failed: %s", strerror(errno));
+
+#if TEST_PROTO == SOCK_STREAM
+ do {} while (send(fd, buf, sendspace, 0) == (ssize_t)sendspace);
+#elif TEST_PROTO == SOCK_DGRAM
+ u_long recvspace = getrecvspace();
+
+ for (ssize_t sent = 0;
+ sent + sendspace + sizeof(struct sockaddr) < recvspace;
+ sent += sendspace + sizeof(struct sockaddr))
+ ATF_REQUIRE(send(fd, buf, sendspace, 0) == (ssize_t)sendspace);
+#endif
+ free(buf);
+}
+
/*
* Put a temporary file into a UNIX domain socket, then take it out and make
* sure it's the same file. First time around, don't close the reference
@@ -469,6 +511,35 @@ ATF_TC_BODY(send_a_lot, tc)
#endif
}
+/*
+ * Exersize condition when SCM_RIGHTS is successfully internalized, but
+ * message delivery fails due to receive buffer overflow. Check that no
+ * file descriptors are leaked.
+ */
+ATF_TC_WITHOUT_HEAD(send_overflow);
+ATF_TC_BODY(send_overflow, tc)
+{
+ void *buf;
+ ssize_t len;
+ int fd[2], putfd, nfiles;
+ int sendspace;
+
+ sendspace = (int)getsendspace();
+ ATF_REQUIRE((buf = malloc(sendspace)) != NULL);
+
+ domainsocketpair(fd);
+ fill(fd[0]);
+ nfiles = openfiles();
+ tempfile(&putfd);
+ len = sendfd_payload(fd[0], putfd, buf, sendspace);
+ ATF_REQUIRE_MSG(len == -1 && errno == EAGAIN,
+ "sendmsg: %zu bytes sent, errno %d", len, errno);
+ close(putfd);
+ ATF_REQUIRE(nfiles == openfiles());
+ closesocketpair(fd);
+}
+
+
/*
* Send two files. Then receive them. Make sure they are returned in the
* right order, and both get there.
@@ -881,6 +952,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, send_and_cancel);
ATF_TP_ADD_TC(tp, send_and_shutdown);
ATF_TP_ADD_TC(tp, send_a_lot);
+ ATF_TP_ADD_TC(tp, send_overflow);
ATF_TP_ADD_TC(tp, two_files);
ATF_TP_ADD_TC(tp, bundle);
ATF_TP_ADD_TC(tp, bundle_cancel);