From nobody Fri Oct 30 14:08:12 2026 X-Original-To: dev-commits-src-all@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 4jGNH05KCSz6wwVM for ; Fri, 30 Oct 2026 14:08: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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jGNH01RG6z4qpt for ; Fri, 30 Oct 2026 14:08:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793369292; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=zj++OtRvfC6YoT6PLn7L6/nldt0sVpnKCzmmkL2Owh8=; b=ELl4i1EY2/piB7MY41NXWUtk7tHbHoHy5JoWOfUrjrdpVzzKjnr54qhOhQFC0iX26ZbTbY /TSbtBijIZF7aefvDOq4jjT54SYhcmB8inT3dVdqt/GwMESn2ZBkz2hf4kPQjfyZXwCeIY XrTAhPEaOyVvjqgtoW/mfEKJgMZUOblX3CrNhp0JRO4LrO2DcJ09wCaJlgszvX9MkW/Rg/ e9IoGfD4ecVDHrwQ74kxwkzJZIRN1QRP5ZaR12WjYoze+rmlYIlzcXHDetGgBjyAGRp5Y2 Ym3GMv+HA5YIiCBCYoE8owlfIeQxtv49cmcEefjxn2wcgGMWtWd0Ha99fLA5SQ== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793369292; b=BZqYc1+Xbzn6FbnnSzDiSCSP8UMGblpaovcOov3j3w3MWdsgpA7PMCGNZ/Egun3703J2k5 CJNJNxMioKu+zgKTqHAkC7yu+EygMSQu4WBFjmjf7n+kDgLisE4V1DxEHgv7Tta3b/NzK1 /4YTGayFjfqul5tg3ySFLu6pS/AVVZB5bAnk1eJRBDdcxXiyYq25H3N0hGyRufnjfR/guw NR+IqISlyNTHOULDf2ZRcnl2lMBUvzJK60C3VzZjhE1thHlZnZdcJAKjx3P8e0iTy+H0yh xfVVG6aQxn99Rl/RUEdDG2DCb2hIdpRmDULqxvCIGkK4DAy1eAwdmKMa1Lkz+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793369292; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=zj++OtRvfC6YoT6PLn7L6/nldt0sVpnKCzmmkL2Owh8=; b=xitiNtk0Af0iCWXikwFBIUfgjBtOCrPEKRcg/okNlnXPe722XxMPrmd1uthHfdmdmbyzfY iIAFe52Rllg2UwQkNQ9aWAxddwwKCTvEGRyWviMhi+5E+ryKPJGXzqP15RN9r2mK2zmqB6 jWG/e9e3k9+fTTqTL9NRNNR4y3t0VV8dVZ8F6epGMh/tPcFDkS4R7RpUBhMjsnajzM4AzK fYzpSX1cGf3OPDgmUEgjOkc+U6BZ2x7+Q7JMxNqyWj3LWMWS8pblg/eXBEFHdZR1+cxAgr Itmj2jiSdwxWd9SQA+iJgOfzJ29+casx2W4OTE4xJ0WW1RfLZdha+JiY2MN9FQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4jGNH016KjzVCp for ; Fri, 30 Oct 2026 14:08:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 21b50 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 30 Oct 2026 14:08:12 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Avinash Duduskar From: Kristof Provost Subject: git: a94a6326507c - main - pf tests: exercise pfctl -l across a privilege drop List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: Commit messages for all branches of the src repository 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: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a94a6326507c5a901adee15bf3844eaf60479ab1 Auto-Submitted: auto-generated Date: Fri, 30 Oct 2026 14:08:12 +0000 Message-Id: <6ae4a4cc.21b50.53afcd59@gitrepo.freebsd.org> The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=a94a6326507c5a901adee15bf3844eaf60479ab1 commit a94a6326507c5a901adee15bf3844eaf60479ab1 Author: Avinash Duduskar AuthorDate: 2026-10-26 14:38:12 +0000 Commit: Kristof Provost CommitDate: 2026-10-30 14:07:25 +0000 pf tests: exercise pfctl -l across a privilege drop Open /dev/pf and a generic Netlink socket as root, drop to nobody and exec pfctl with both inherited, the way authpf(8) runs it. Without -l the load is refused with EPERM; with it the rules land in the anchor. An unusable descriptor is an error, not a fallback to a new socket. Skips when fdescfs is not mounted, which -p /dev/fd/N needs. PR: 291981 Signed-off-by: Avinash Duduskar Reviewed by: kp Pull Request: https://github.com/freebsd/freebsd-src/pull/2508 --- tests/sys/netpfil/pf/Makefile | 3 ++ tests/sys/netpfil/pf/authpf.sh | 75 +++++++++++++++++++++++++++++++++++++ tests/sys/netpfil/pf/pfctl_adopt.py | 43 +++++++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile index c95bac83c92c..be3ac9f91486 100644 --- a/tests/sys/netpfil/pf/Makefile +++ b/tests/sys/netpfil/pf/Makefile @@ -5,6 +5,7 @@ TESTS_SUBDIRS+= ioctl ATF_TESTS_SH+= altq \ anchor \ + authpf \ counters \ debug \ divert-to \ @@ -89,6 +90,7 @@ ${PACKAGE}FILES+= \ frag-overreplace.py \ frag-overhole.py \ frag-adjhole.py \ + pfctl_adopt.py \ pfsync_defer.py \ pft_ether.py \ pft_read_ipfix.py \ @@ -107,6 +109,7 @@ ${PACKAGE}FILESMODE_frag-overlimit.py= 0555 ${PACKAGE}FILESMODE_frag-overreplace.py= 0555 ${PACKAGE}FILESMODE_frag-overhole.py= 0555 ${PACKAGE}FILESMODE_frag-adjhole.py= 0555 +${PACKAGE}FILESMODE_pfctl_adopt.py= 0555 ${PACKAGE}FILESMODE_pfsync_defer.py= 0555 ${PACKAGE}FILESMODE_pft_ether.py= 0555 ${PACKAGE}FILESMODE_pft_read_ipfix.py= 0555 diff --git a/tests/sys/netpfil/pf/authpf.sh b/tests/sys/netpfil/pf/authpf.sh new file mode 100644 index 000000000000..38cb80e94dc1 --- /dev/null +++ b/tests/sys/netpfil/pf/authpf.sh @@ -0,0 +1,75 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2026 Avinash Duduskar +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# 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. + +. $(atf_get_srcdir)/utils.subr + +atf_test_case "pfctl_adopt" "cleanup" +pfctl_adopt_head() +{ + atf_set descr 'pfctl -l across a privilege drop, as authpf(8) runs it' + atf_set require.user root + atf_set require.progs python3 +} + +pfctl_adopt_body() +{ + pft_init + + # pfctl is handed /dev/pf as -p /dev/fd/N, which needs fdescfs. + if ! ( exec 3 +# +# Run pfctl as authpf(8) does: open /dev/pf and a Netlink socket as root, +# drop to nobody, exec pfctl with -p /dev/fd/N and, given -l, -l M. + +import os +import pwd +import socket +import sys + +AF_NETLINK = 38 # sys/socket.h; not exported by the socket module +NETLINK_GENERIC = 16 # netlink/netlink.h + + +def main(): + args = sys.argv[1:] + adopt = False + if args and args[0] == "-l": + adopt = True + args = args[1:] + + dev = os.open("/dev/pf", os.O_RDWR) + os.set_inheritable(dev, True) + nl = socket.socket(AF_NETLINK, socket.SOCK_RAW, NETLINK_GENERIC) + os.set_inheritable(nl.fileno(), True) + + pw = pwd.getpwnam("nobody") + os.setgroups([pw.pw_gid]) + os.setgid(pw.pw_gid) + os.setuid(pw.pw_uid) + + argv = ["pfctl", "-p", "/dev/fd/%d" % dev] + if adopt: + argv += ["-l", str(nl.fileno())] + os.execv("/sbin/pfctl", argv + args) + + +if __name__ == "__main__": + main()