From owner-svn-src-all@freebsd.org Sat Aug 4 20:29:59 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8F9DE1052105; Sat, 4 Aug 2018 20:29:59 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 17E9386DA9; Sat, 4 Aug 2018 20:29:59 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id ED46914576; Sat, 4 Aug 2018 20:29:58 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w74KTwxZ006643; Sat, 4 Aug 2018 20:29:58 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w74KTwUf006642; Sat, 4 Aug 2018 20:29:58 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201808042029.w74KTwUf006642@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Sat, 4 Aug 2018 20:29:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r337329 - head/tests/sys/kern X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: head/tests/sys/kern X-SVN-Commit-Revision: 337329 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Aug 2018 20:29:59 -0000 Author: markj Date: Sat Aug 4 20:29:58 2018 New Revision: 337329 URL: https://svnweb.freebsd.org/changeset/base/337329 Log: Fix the regression test for PR 181741. With r337328, the test hangs becase the sendmsg() call will block until the receive buffer is at least partially drained. Fix the problem by using a non-blocking socket and allowing short writes. Also assert that a SCM_CREDS message was received if one was expected. PR: 181741 MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D16516 Modified: head/tests/sys/kern/unix_passfd_test.c Modified: head/tests/sys/kern/unix_passfd_test.c ============================================================================== --- head/tests/sys/kern/unix_passfd_test.c Sat Aug 4 20:26:54 2018 (r337328) +++ head/tests/sys/kern/unix_passfd_test.c Sat Aug 4 20:29:58 2018 (r337329) @@ -126,7 +126,7 @@ samefile(struct stat *sb1, struct stat *sb2) ATF_REQUIRE_MSG(sb1->st_ino == sb2->st_ino, "different inode"); } -static void +static size_t sendfd_payload(int sockfd, int send_fd, void *payload, size_t paylen) { struct iovec iovec; @@ -153,21 +153,37 @@ sendfd_payload(int sockfd, int send_fd, void *payload, cmsghdr->cmsg_type = SCM_RIGHTS; memcpy(CMSG_DATA(cmsghdr), &send_fd, sizeof(int)); - len = sendmsg(sockfd, &msghdr, 0); + len = sendmsg(sockfd, &msghdr, MSG_DONTWAIT); ATF_REQUIRE_MSG(len != -1, "sendmsg failed: %s", strerror(errno)); - ATF_REQUIRE_MSG((size_t)len == paylen, - "sendmsg: %zd messages sent; expected: %zu; %s", len, paylen, - strerror(errno)); + return ((size_t)len); } static void sendfd(int sockfd, int send_fd) { - char ch = 0; + size_t len; + char ch; - sendfd_payload(sockfd, send_fd, &ch, sizeof(ch)); + ch = 0; + len = sendfd_payload(sockfd, send_fd, &ch, sizeof(ch)); + ATF_REQUIRE_MSG(len == sizeof(ch), + "sendmsg: %zu bytes sent; expected %zu; %s", len, sizeof(ch), + strerror(errno)); } +static bool +localcreds(int sockfd) +{ + socklen_t sz; + int rc, val; + + sz = sizeof(val); + rc = getsockopt(sockfd, 0, LOCAL_CREDS, &val, &sz); + ATF_REQUIRE_MSG(rc != -1, "getsockopt(LOCAL_CREDS) failed: %s", + strerror(errno)); + return (val != 0); +} + static void recvfd_payload(int sockfd, int *recv_fd, void *buf, size_t buflen) { @@ -177,6 +193,7 @@ recvfd_payload(int sockfd, int *recv_fd, void *buf, si struct msghdr msghdr; struct iovec iovec; ssize_t len; + bool foundcreds; bzero(&msghdr, sizeof(msghdr)); @@ -197,6 +214,7 @@ recvfd_payload(int sockfd, int *recv_fd, void *buf, si cmsghdr = CMSG_FIRSTHDR(&msghdr); ATF_REQUIRE_MSG(cmsghdr != NULL, "recvmsg: did not receive control message"); + foundcreds = false; *recv_fd = -1; for (; cmsghdr != NULL; cmsghdr = CMSG_NXTHDR(&msghdr, cmsghdr)) { if (cmsghdr->cmsg_level == SOL_SOCKET && @@ -204,10 +222,14 @@ recvfd_payload(int sockfd, int *recv_fd, void *buf, si cmsghdr->cmsg_len == CMSG_LEN(sizeof(int))) { memcpy(recv_fd, CMSG_DATA(cmsghdr), sizeof(int)); ATF_REQUIRE(*recv_fd != -1); - } + } else if (cmsghdr->cmsg_level == SOL_SOCKET && + cmsghdr->cmsg_type == SCM_CREDS) + foundcreds = true; } ATF_REQUIRE_MSG(*recv_fd != -1, "recvmsg: did not receive single-fd message"); + ATF_REQUIRE_MSG(!localcreds(sockfd) || foundcreds, + "recvmsg: expected credentials were not received"); } static void @@ -362,9 +384,9 @@ ATF_TC_BODY(devfs_orphan, tc) /* * Test for PR 181741. Receiver sets LOCAL_CREDS, and kernel prepends a - * control message to the data. Sender sends large payload. - * Payload + SCM_RIGHTS + LOCAL_CREDS hit socket buffer limit, and receiver - * receives truncated data. + * control message to the data. Sender sends large payload using a non-blocking + * socket. Payload + SCM_RIGHTS + LOCAL_CREDS hit socket buffer limit, and + * receiver receives truncated data. */ ATF_TC_WITHOUT_HEAD(rights_creds_payload); ATF_TC_BODY(rights_creds_payload, tc) @@ -375,9 +397,6 @@ ATF_TC_BODY(rights_creds_payload, tc) void *buf; int fd[2], getfd, putfd, rc; - atf_tc_expect_fail("PR 181741: Packet loss when 'control' messages " - "are present with large data"); - len = sizeof(sendspace); rc = sysctlbyname(LOCAL_SENDSPACE_SYSCTL, &sendspace, &len, NULL, 0); @@ -388,12 +407,19 @@ ATF_TC_BODY(rights_creds_payload, tc) ATF_REQUIRE(buf != NULL); domainsocketpair(fd); + tempfile(&putfd); + + rc = fcntl(fd[0], F_SETFL, O_NONBLOCK); + ATF_REQUIRE_MSG(rc != -1, "fcntl(O_NONBLOCK) failed: %s", + strerror(errno)); rc = setsockopt(fd[1], 0, LOCAL_CREDS, &on, sizeof(on)); ATF_REQUIRE_MSG(rc != -1, "setsockopt(LOCAL_CREDS) failed: %s", strerror(errno)); - tempfile(&putfd); - sendfd_payload(fd[0], putfd, buf, sendspace); - recvfd_payload(fd[1], &getfd, buf, sendspace); + + len = sendfd_payload(fd[0], putfd, buf, sendspace); + ATF_REQUIRE_MSG(len < sendspace, "sendmsg: %zu bytes sent", len); + recvfd_payload(fd[1], &getfd, buf, len); + close(putfd); close(getfd); closesocketpair(fd); @@ -421,7 +447,10 @@ ATF_TC_BODY(truncated_rights, tc) 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 == sizeof(buf), + "sendmsg: %zd bytes sent; expected %zu; %s", len, sizeof(buf), + strerror(errno)); bzero(&msghdr, sizeof(msghdr)); bzero(message, sizeof(message));