Author: markj
Date: Sun Jul 22 18:07:08 2018
New Revision: 336614
URL: https://svnweb.freebsd.org/changeset/base/336614

Log:
  Add a regression test for PR 131876.
  
  PR:           131876
  MFC after:    1 week

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      Sun Jul 22 18:06:42 2018        
(r336613)
+++ head/tests/sys/kern/unix_passfd_test.c      Sun Jul 22 18:07:08 2018        
(r336614)
@@ -23,10 +23,11 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
@@ -100,6 +101,23 @@ dofstat(int fd, struct stat *sb)
            "fstat failed: %s", strerror(errno));
 }
 
+static int
+getnfds(void)
+{
+       size_t len;
+       int mib[4], n, rc;
+
+       len = sizeof(n);
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_PROC;
+       mib[2] = KERN_PROC_NFDS;
+       mib[3] = 0;
+
+       rc = sysctl(mib, 4, &n, &len, NULL, 0);
+       ATF_REQUIRE_MSG(rc != -1, "sysctl(KERN_PROC_NFDS) failed");
+       return (n);
+}
+
 static void
 samefile(struct stat *sb1, struct stat *sb2)
 {
@@ -129,7 +147,7 @@ sendfd_payload(int sockfd, int send_fd, void *payload,
        msghdr.msg_iov = &iovec;
        msghdr.msg_iovlen = 1;
 
-       cmsghdr = (struct cmsghdr *)(void*)message;
+       cmsghdr = (struct cmsghdr *)(void *)message;
        cmsghdr->cmsg_len = CMSG_LEN(sizeof(int));
        cmsghdr->cmsg_level = SOL_SOCKET;
        cmsghdr->cmsg_type = SCM_RIGHTS;
@@ -380,6 +398,55 @@ ATF_TC_BODY(rights_creds_payload, tc)
        closesocketpair(fd);
 }
 
+/*
+ * Test for PR 131876. Receiver uses a control message buffer that is too
+ * small for the incoming SCM_RIGHTS message, so the message is truncated.
+ * The kernel must not leak the copied right into the receiver's namespace.
+ */
+ATF_TC_WITHOUT_HEAD(truncated_rights);
+ATF_TC_BODY(truncated_rights, tc)
+{
+       struct iovec iovec;
+       struct msghdr msghdr;
+       char buf[16], message[CMSG_SPACE(0)];
+       ssize_t len;
+       int fd[2], nfds, putfd;
+
+       atf_tc_expect_fail("PR 131876: "
+           "FD leak when 'control' message is truncated");
+
+       memset(buf, 42, sizeof(buf));
+       domainsocketpair(fd);
+       devnull(&putfd);
+       nfds = getnfds();
+
+       sendfd_payload(fd[0], putfd, buf, sizeof(buf));
+
+       bzero(&msghdr, sizeof(msghdr));
+       bzero(message, sizeof(message));
+
+       iovec.iov_base = buf;
+       iovec.iov_len = sizeof(buf);
+       msghdr.msg_control = message;
+       msghdr.msg_controllen = sizeof(message);
+       msghdr.msg_iov = &iovec;
+       msghdr.msg_iovlen = 1;
+
+       len = recvmsg(fd[1], &msghdr, 0);
+       ATF_REQUIRE_MSG(len != -1, "recvmsg failed: %s", strerror(errno));
+       ATF_REQUIRE_MSG((size_t)len == sizeof(buf),
+           "recvmsg: %zd bytes received; expected %zd", len, sizeof(buf));
+       for (size_t i = 0; i < sizeof(buf); i++)
+               ATF_REQUIRE_MSG(buf[i] == 42, "unexpected buffer contents");
+
+       ATF_REQUIRE_MSG((msghdr.msg_flags & MSG_CTRUNC) != 0,
+           "MSG_CTRUNC not set after truncation");
+       ATF_REQUIRE(getnfds() == nfds);
+
+       close(putfd);
+       closesocketpair(fd);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 
@@ -391,6 +458,7 @@ ATF_TP_ADD_TCS(tp)
        ATF_TP_ADD_TC(tp, bundle_cancel);
        ATF_TP_ADD_TC(tp, devfs_orphan);
        ATF_TP_ADD_TC(tp, rights_creds_payload);
+       ATF_TP_ADD_TC(tp, truncated_rights);
 
        return (atf_no_error());
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to