From nobody Fri Jun 19 04:05:12 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4ghPBc65KVz6hPp9 for ; Fri, 19 Jun 2026 04:05:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ghPBc38R7z3X4G for ; Fri, 19 Jun 2026 04:05:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781841912; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=CpIyDDPOB3GWbxjz25v8EuWIi31cNSDryjhRI6x8/48=; b=S9SOaO9y6+8S3SXIzqmu4tYf3guBKGGuLdC/hQUedg6CRJy0dn4RP74hU1W6mCqhqp0E3J Oe0GHVw8oE2LeZ3VcYxVb/XjqAv4w2YFbktrxwrXcstLVIPl1YlLFLhtYLqMbwUbUajDnp ZnJHIUru7kMMazre9VBl87CbzyWkvQwh8hCVMBuq+G2pWYY+T2/zWih+c1KpoxrNdOU6f+ noBrdQk8bMeBxRSP3k34oaK7Y7zXeQw2uWEZ9ePs7LwMAGOXz7Z6zhjn1F40OzEG7FkZjs 2lhtv4FEO6p1Uu4ISfWVylYTJzTsHjRUePKvWRNjQk8BmD3ZyrvKp7kNltZJ9Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1781841912; a=rsa-sha256; cv=none; b=tdTKqtWwqHB6aA/m1Mz2Yc1Ic7tdxVH94NKnzIytkYBdQ0dP48YmU7kJz710aZaE8mL7bI Q26iIcjoloV7nknv+uwC/SBosSvdDWxM8G896QekwvBsKJLHVUcQIymIpD1Kr2ab2+UQ8U 3AhOyGu5vFZhlK45h7elhHb2+WV5N6RfV+NdppmfvfvM2G+ASs/nUnnIFVWogUIPgSguav bkDor3lacP9rvmJe1G3dQ1rdHlAfZdePBehUfzti+IJ5kkVj5LjuwO2awJwjfBNoVuLZ9N IAqXxI5Epu1zQD0HqwnHcNP3x0yUKnrGLiGs1nPV0Eyz//fWxVH09R+3V2hK/Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781841912; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=CpIyDDPOB3GWbxjz25v8EuWIi31cNSDryjhRI6x8/48=; b=XkSN4A3Kp1o8MgjWbCMdkcOZGKFBGSz1H7782uHIHw6OXOrIHGJW4EyK/gjDCuWHfsFxl+ eqHEmMxQooYbVMRWWRrBh9kcKwComo7E4KbdNUlf6YeOoM3PW7v1W98b0bd/MCQh+xSuG1 49OK6X6OGjNfJs6DQn6P8MFGuBE+PynuBRwjRlzJE8oAx/AfPcmZomE5sD/lEkHTuFngd5 VDchE8cCi7tbHf3V9zuQUe52+kym666Yte173kp65uoQlxr41BaVoPmuD0BqqEr9o1Crg2 xQue3JKRrogwU+iIJcwUd+JcdNV2CKa3yxn3/HHgGqYlTc2Fa+HLQAZjg3f+bA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4ghPBc1g8FzD9S for ; Fri, 19 Jun 2026 04:05:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 194a9 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 19 Jun 2026 04:05:12 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kyle Evans Subject: git: c08a86e0c6d9 - main - tests: unix: add SCM_RIGHTS tests for SO_PASSRIGHTS List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c08a86e0c6d989c926c2777c978155dde7d0697a Auto-Submitted: auto-generated Date: Fri, 19 Jun 2026 04:05:12 +0000 Message-Id: <6a34bff8.194a9.4ceada7b@gitrepo.freebsd.org> The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=c08a86e0c6d989c926c2777c978155dde7d0697a commit c08a86e0c6d989c926c2777c978155dde7d0697a Author: Kyle Evans AuthorDate: 2026-06-19 04:03:30 +0000 Commit: Kyle Evans CommitDate: 2026-06-19 04:03:30 +0000 tests: unix: add SCM_RIGHTS tests for SO_PASSRIGHTS We test both the standard case where we want to reject any SCM_RIGHTS message, as well as the case where the kernel discards the unwanted file upon receipt. Reviewed by: glebius (previous version), markj Differential Revision: https://reviews.freebsd.org/D57426 --- tests/sys/kern/unix_passfd_test.c | 150 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/tests/sys/kern/unix_passfd_test.c b/tests/sys/kern/unix_passfd_test.c index 2ad40582d058..c600b0937b0d 100644 --- a/tests/sys/kern/unix_passfd_test.c +++ b/tests/sys/kern/unix_passfd_test.c @@ -208,6 +208,19 @@ localcreds(int sockfd) return (val != 0); } +static bool +passrights(int sockfd) +{ + socklen_t sz; + int rc, val; + + sz = sizeof(val); + rc = getsockopt(sockfd, SOL_SOCKET, SO_PASSRIGHTS, &val, &sz); + ATF_REQUIRE_MSG(rc != -1, "getsockopt(SO_PASSRIGHTS) failed: %s", + strerror(errno)); + return (val != 0); +} + static ssize_t recvfd_payload_cmsg(int sockfd, void *buf, size_t buflen, struct msghdr *msghdr, int recvmsg_flags) @@ -580,6 +593,140 @@ ATF_TC_BODY(send_overflow, tc) closesocketpair(fd); } +ATF_TC_WITHOUT_HEAD(send_rejected); +ATF_TC_BODY(send_rejected, tc) +{ + ssize_t len; + int fd[2], optval, putfd, rc; + char ch; + + domainsocketpair(fd); + ATF_REQUIRE_MSG(passrights(fd[0]), + "socketpair socket not initialized with SO_PASSRIGHTS"); + ATF_REQUIRE_MSG(passrights(fd[1]), + "socketpair socket not initialized with SO_PASSRIGHTS"); + + tempfile(&putfd); + + /* Toggle SO_PASSRIGHTS off on the receiver side. */ + optval = 0; + rc = setsockopt(fd[1], SOL_SOCKET, SO_PASSRIGHTS, &optval, + sizeof(optval)); + ATF_REQUIRE_MSG(rc != -1, "setsockopt(SO_PASSRIGHTS) failed: %s", + strerror(errno)); + /* Confirm that the sender-side didn't reflect that... */ + ATF_REQUIRE_MSG(passrights(fd[0]), + "setsockopt(SO_PASSRIGHTS) switched the sender"); + /* ... and that the receiver-side did. */ + ATF_REQUIRE_MSG(!passrights(fd[1]), + "setsockopt(SO_PASSRIGHTS) did not switch the receiver"); + + ch = 0; + len = sendfd_payload(fd[0], putfd, &ch, sizeof(ch)); + ATF_REQUIRE_MSG(len == -1, + "sending SCM_RIGHTS with SO_PASSRIGHTS disabled on peer did not fail"); + ATF_REQUIRE_MSG(errno == EPERM, + "bad SCM_RIGHTS failure: %s", strerror(errno)); + closesocketpair(fd); +} + +ATF_TC_WITHOUT_HEAD(send_rejected_late); +ATF_TC_BODY(send_rejected_late, tc) +{ + struct cmsghdr *cmsghdr; + struct msghdr msghdr; + ssize_t len; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; + int fd[2], nfds, optval, putfd, rc; + char ch; +#define MAGIC_VAL 42 + + domainsocketpair(fd); + tempfile(&putfd); + + nfds = getnfds(); + + ch = MAGIC_VAL; + len = sendfd_payload(fd[0], putfd, &ch, sizeof(ch)); + ATF_REQUIRE_MSG(len == sizeof(ch), + "valid send of SCM_RIGHTS failed: %s", strerror(errno)); + + /* + * Toggle SO_PASSRIGHTS off on the receiver side. The subsequent recv + * should actually succeed, we just won't have an fd installed. + */ + optval = 0; + rc = setsockopt(fd[1], SOL_SOCKET, SO_PASSRIGHTS, &optval, + sizeof(optval)); + ATF_REQUIRE_MSG(rc != -1, "setsockopt(SO_PASSRIGHTS) failed: %s", + strerror(errno)); + + bzero(&msghdr, sizeof(msghdr)); + msghdr.msg_control = &cmsgbuf[0]; + msghdr.msg_controllen = sizeof(cmsgbuf); + + ch = 0; + len = recvfd_payload_cmsg(fd[1], &ch, sizeof(ch), &msghdr, 0); + /* We want to confirm that we still received the sent byte... */ + ATF_REQUIRE_MSG(len == sizeof(ch), "recvmsg should have returned data"); + ATF_REQUIRE_MSG(ch == MAGIC_VAL, "recvmsg returned garbage? %d", ch); + + /* ... and make sure we did not receive any descriptors! */ + cmsghdr = CMSG_FIRSTHDR(&msghdr); + ATF_REQUIRE_MSG(cmsghdr == NULL || cmsghdr->cmsg_type != SCM_RIGHTS, + "recvmsg unexpectedly received a descriptor"); + ATF_REQUIRE(getnfds() == nfds); + closesocketpair(fd); +} + +ATF_TC_WITHOUT_HEAD(send_rejected_noinherit); +ATF_TC_BODY(send_rejected_noinherit, tc) +{ + struct sockaddr_un sun; + int clsock, connsock, ls, optval, rc; + + ls = socket(AF_UNIX, SOCK_STREAM, 0); + ATF_REQUIRE(ls != -1); + + optval = 0; + rc = setsockopt(ls, SOL_SOCKET, SO_PASSRIGHTS, &optval, + sizeof(optval)); + ATF_REQUIRE_MSG(rc != -1, "setsockopt(SO_PASSRIGHTS) failed: %s", + strerror(errno)); + + memset(&sun, 0, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + snprintf(sun.sun_path, sizeof(sun.sun_path), "listen.sock"); + rc = bind(ls, (struct sockaddr *)&sun, sizeof(sun)); + ATF_REQUIRE_MSG(rc == 0, "bind failed: %s", strerror(errno)); + rc = listen(ls, 0); + ATF_REQUIRE_MSG(rc == 0, "listen failed: %s", strerror(errno)); + + ATF_REQUIRE_MSG(!passrights(ls), + "listening socket lost its SO_PASSRIGHTS setting"); + + connsock = socket(AF_UNIX, SOCK_STREAM, 0); + ATF_REQUIRE_MSG(connsock != -1, "connect failed: %s", strerror(errno)); + + rc = connect(connsock, (const struct sockaddr *)&sun, + sizeof(sun)); + ATF_REQUIRE_MSG(rc == 0, "connect failed: %s", strerror(errno)); + + /* + * Finally, accept(4) and confirm that the new socket has + * SO_PASSRIGHTS set. + */ + clsock = accept(ls, NULL, NULL); + ATF_REQUIRE_MSG(clsock >= 0, "accept failed: %s", strerror(errno)); + + ATF_REQUIRE_MSG(passrights(clsock), + "inherited socket should enable SO_PASSRIGHTS"); + close(clsock); + close(connsock); + close(ls); +} + /* * Make sure that we do not receive descriptors with MSG_PEEK. */ @@ -1236,6 +1383,9 @@ ATF_TP_ADD_TCS(tp) 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, send_rejected); + ATF_TP_ADD_TC(tp, send_rejected_late); + ATF_TP_ADD_TC(tp, send_rejected_noinherit); ATF_TP_ADD_TC(tp, peek); ATF_TP_ADD_TC(tp, two_files); ATF_TP_ADD_TC(tp, bundle);