From owner-svn-src-all@FreeBSD.ORG Thu Apr 9 16:52:54 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 30F72555; Thu, 9 Apr 2015 16:52:54 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 116206CB; Thu, 9 Apr 2015 16:52:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t39Gqr28008590; Thu, 9 Apr 2015 16:52:53 GMT (envelope-from ngie@FreeBSD.org) Received: (from ngie@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t39Gqr43008589; Thu, 9 Apr 2015 16:52:53 GMT (envelope-from ngie@FreeBSD.org) Message-Id: <201504091652.t39Gqr43008589@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ngie set sender to ngie@FreeBSD.org using -f From: Garrett Cooper Date: Thu, 9 Apr 2015 16:52:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r281314 - stable/9/tools/regression/sockets/unix_passfd X-SVN-Group: stable-9 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.18-1 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: Thu, 09 Apr 2015 16:52:54 -0000 Author: ngie Date: Thu Apr 9 16:52:53 2015 New Revision: 281314 URL: https://svnweb.freebsd.org/changeset/base/281314 Log: MFstable/10 r228371: This missing MFC fixes PR 199308 r228371 (by jhb): - Add a test for PR 151758. - While here, make this compile and work on non-i386: - Use CMSG_SPACE(), CMSG_LEN(), and CMSG_FIRSTHDR() instead of ignoring padding between 'struct cmsghdr' and control message payloads. - Don't initialize the control message before calling recvmsg(). Instead, check that we get a valid control message on return from recvmsg(). - Use errx() instead of err() for some errors that don't report failures that set errno. Requested by: kib (1) Modified: stable/9/tools/regression/sockets/unix_passfd/unix_passfd.c Directory Properties: stable/9/ (props changed) stable/9/tools/ (props changed) stable/9/tools/regression/ (props changed) stable/9/tools/regression/sockets/ (props changed) Modified: stable/9/tools/regression/sockets/unix_passfd/unix_passfd.c ============================================================================== --- stable/9/tools/regression/sockets/unix_passfd/unix_passfd.c Thu Apr 9 15:08:39 2015 (r281313) +++ stable/9/tools/regression/sockets/unix_passfd/unix_passfd.c Thu Apr 9 16:52:53 2015 (r281314) @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,17 @@ closesocketpair(int *fdp) } static void +devnull(const char *test, int *fdp) +{ + int fd; + + fd = open("/dev/null", O_RDONLY); + if (fd < 0) + err(-1, "%s: open(/dev/null)", test); + *fdp = fd; +} + +static void tempfile(const char *test, int *fdp) { char path[PATH_MAX]; @@ -88,9 +100,9 @@ samefile(const char *test, struct stat * { if (sb1->st_dev != sb2->st_dev) - err(-1, "%s: samefile: different device", test); + errx(-1, "%s: samefile: different device", test); if (sb1->st_ino != sb2->st_ino) - err(-1, "%s: samefile: different inode", test); + errx(-1, "%s: samefile: different inode", test); } static void @@ -99,10 +111,8 @@ sendfd(const char *test, int sockfd, int struct iovec iovec; char ch; - struct { - struct cmsghdr cmsghdr; - int fd; - } message; + char message[CMSG_SPACE(sizeof(int))]; + struct cmsghdr *cmsghdr; struct msghdr msghdr; ssize_t len; @@ -110,7 +120,7 @@ sendfd(const char *test, int sockfd, int bzero(&message, sizeof(message)); ch = 0; - msghdr.msg_control = &message; + msghdr.msg_control = message; msghdr.msg_controllen = sizeof(message); iovec.iov_base = &ch; @@ -119,35 +129,33 @@ sendfd(const char *test, int sockfd, int msghdr.msg_iov = &iovec; msghdr.msg_iovlen = 1; - message.cmsghdr.cmsg_len = sizeof(message); - message.cmsghdr.cmsg_level = SOL_SOCKET; - message.cmsghdr.cmsg_type = SCM_RIGHTS; - message.fd = sendfd; + cmsghdr = (struct cmsghdr *)message; + cmsghdr->cmsg_len = CMSG_LEN(sizeof(int)); + cmsghdr->cmsg_level = SOL_SOCKET; + cmsghdr->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsghdr) = sendfd; len = sendmsg(sockfd, &msghdr, 0); if (len < 0) err(-1, "%s: sendmsg", test); if (len != sizeof(ch)) - errx(-1, "%s: sendmsg: %d bytes sent", test, len); + errx(-1, "%s: sendmsg: %zd bytes sent", test, len); } static void recvfd(const char *test, int sockfd, int *recvfd) { - struct { - struct cmsghdr cmsghdr; - int fd; - } message; + struct cmsghdr *cmsghdr; + char message[CMSG_SPACE(sizeof(int))]; struct msghdr msghdr; struct iovec iovec; ssize_t len; char ch; bzero(&msghdr, sizeof(msghdr)); - bzero(&message, sizeof(message)); ch = 0; - msghdr.msg_control = &message; + msghdr.msg_control = message; msghdr.msg_controllen = sizeof(message); iovec.iov_base = &ch; @@ -161,19 +169,22 @@ recvfd(const char *test, int sockfd, int msghdr.msg_iov = &iovec; msghdr.msg_iovlen = 1; - message.cmsghdr.cmsg_len = sizeof(message); - message.cmsghdr.cmsg_level = SOL_SOCKET; - message.cmsghdr.cmsg_type = SCM_RIGHTS; - message.fd = -1; - len = recvmsg(sockfd, &msghdr, 0); if (len < 0) err(-1, "%s: recvmsg", test); if (len != sizeof(ch)) - errx(-1, "%s: recvmsg: %d bytes received", test, len); - if (message.fd == -1) + errx(-1, "%s: recvmsg: %zd bytes received", test, len); + cmsghdr = CMSG_FIRSTHDR(&msghdr); + if (cmsghdr == NULL) + errx(-1, "%s: recvmsg: did not receive control message", test); + if (cmsghdr->cmsg_len != CMSG_LEN(sizeof(int)) || + cmsghdr->cmsg_level != SOL_SOCKET || + cmsghdr->cmsg_type != SCM_RIGHTS) + errx(-1, "%s: recvmsg: did not receive single-fd message", + test); + *recvfd = *(int *)CMSG_DATA(cmsghdr); + if (*recvfd == -1) errx(-1, "%s: recvmsg: received fd -1", test); - *recvfd = message.fd; } int @@ -303,5 +314,22 @@ main(int argc, char *argv[]) printf("%s passed\n", test); + /* + * Test for PR 151758: Send an character device over the UNIX + * domain socket and then close both sockets to orphan the + * device. + */ + + test = "test7-devfsorphan"; + printf("beginning %s\n", test); + + domainsocketpair(test, fd); + devnull(test, &putfd_1); + sendfd(test, fd[0], putfd_1); + close(putfd_1); + closesocketpair(fd); + + printf("%s passed\n", test); + return (0); }