Re: authpf: kill states in the session's routing domain
Avinash Duduskar <[email protected]> Fri, 24 Jul 2026 17:11:07 +0530
| Newsgroups | gmane.os.openbsd.tech |
|---|---|
| Message-ID | <[email protected]> |
From: Avinash H. Duduskar <[email protected]> On Fri, Jul 24, 2026 at 07:43:59AM +0000, Alexandr Nedvedicky wrote: > Also I'm not sure if the plan for sysctl(2) error handling > is good. I think better course of action is to do exit(1) > instead of returning rtable assuming this is what we are > asking for. Agreed, exit(1) is better. Falling back to the raw rtable guesses a mapping, and a wrong guess aims the kill at a domain where nothing matches, the same silent no-op this diff exists to fix. The sysctl failing for the table the process runs in should not happen; if it does, the syslog line records why we bailed. Updated diff below, thanks for the review. diff --git a/usr.sbin/authpf/authpf.c b/usr.sbin/authpf/authpf.c index ab227dc6d19..a2ab2de8356 100644 --- a/usr.sbin/authpf/authpf.c +++ b/usr.sbin/authpf/authpf.c @@ -20,12 +20,14 @@ #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/stat.h> +#include <sys/sysctl.h> #include <sys/wait.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <net/pfvar.h> +#include <net/route.h> #include <err.h> #include <errno.h> @@ -51,6 +53,7 @@ static int remove_stale_rulesets(void); static int recursive_ruleset_purge(char *, char *); static int change_filter(int, const char *, const char *); static int change_table(int, const char *); +static u_int authpf_rdomain(void); static void authpf_kill_states(void); int dev; /* pf device */ @@ -889,6 +892,32 @@ change_table(int add, const char *ipsrc) return (0); } +/* + * Map the process routing table to its routing domain; a policy-routing + * rtable lives in rdomain 0. + */ +static u_int +authpf_rdomain(void) +{ + struct rt_tableinfo info; + int mib[6]; + size_t len = sizeof(info); + int rtable = getrtable(); + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = 0; + mib[4] = NET_RT_TABLE; + mib[5] = rtable; + + if (sysctl(mib, 6, &info, &len, NULL, 0) == -1) { + syslog(LOG_ERR, "sysctl NET_RT_TABLE: %m"); + exit(1); + } + return (info.rti_domainid); +} + /* * This is to kill off states that would otherwise be left behind stateful * rules. This means we don't need to allow in more traffic than we really @@ -905,6 +934,12 @@ authpf_kill_states(void) memset(&psk, 0, sizeof(psk)); memset(&target, 0, sizeof(target)); + /* + * DIOCKILLSTATES matches psk_rdomain exactly, so kill in the + * routing domain the session runs in, not just rdomain 0. + */ + psk.psk_rdomain = authpf_rdomain(); + if (inet_pton(AF_INET, ipsrc, &target.v4) == 1) psk.psk_af = AF_INET; else if (inet_pton(AF_INET6, ipsrc, &target.v6) == 1)