git: 3d5bd2cf202c - main - authpf: deny tracing of the pfctl child

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Fri, 30 Oct 2026 14:08:11 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=3d5bd2cf202cce4c98e227d8eacc4bb6f937477a

commit 3d5bd2cf202cce4c98e227d8eacc4bb6f937477a
Author:     Avinash Duduskar <avinash.duduskar@gmail.com>
AuthorDate: 2026-10-28 10:22:17 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-10-30 14:07:19 +0000

    authpf: deny tracing of the pfctl child
    
    The child runs pfctl as the user with authpf's root-opened /dev/pf and
    Netlink descriptors. Its real and effective ids match at the exec, so
    the kernel clears P_SUGID and any other process of the user could attach
    to it and take both descriptors. Deny tracing across the exec; root can
    still attach, and core dumps are not affected.
    
    PR:             291981
    Signed-off-by:  Avinash Duduskar <avinash.duduskar@gmail.com>
    Reviewed by:    kp
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/2508
---
 contrib/pf/authpf/authpf.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/contrib/pf/authpf/authpf.c b/contrib/pf/authpf/authpf.c
index 35e3a865bd51..0a76128969e2 100644
--- a/contrib/pf/authpf/authpf.c
+++ b/contrib/pf/authpf/authpf.c
@@ -19,6 +19,9 @@
 #include <sys/types.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
+#ifdef __FreeBSD__
+#include <sys/procctl.h>
+#endif
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -752,6 +755,9 @@ change_filter(int add, const char *l_user, const char *ip_src)
 	pid_t	pid;
 	gid_t   gid;
 	int	s;
+#ifdef __FreeBSD__
+	int	tc = PROC_TRACE_CTL_DISABLE_EXEC;
+#endif
 
 	if (add) {
 		struct stat sb;
@@ -815,6 +821,14 @@ change_filter(int add, const char *l_user, const char *ip_src)
 			    fcntl(pfctl_nl_fd(pfh), F_SETFD, 0) == -1) {
 				err(1, "fcntl");
 			}
+#ifdef __FreeBSD__
+			/*
+			 * The exec clears P_SUGID, so the user could attach to
+			 * pfctl and take the root-opened descriptors.
+			 */
+			if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &tc) == -1)
+				err(1, "procctl");
+#endif
 			execvp(PATH_PFCTL, pargv);
 			warn("exec of %s failed", PATH_PFCTL);
 			_exit(1);