kern/143504: [patch] outgoing states are not killed by authpf

olli hauer ohauer at gmx.de
Tue Feb 2 22:30:02 UTC 2010


>Number:         143504
>Category:       kern
>Synopsis:       [patch] outgoing states are not killed by authpf
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 02 22:30:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     olli hauer <ohauer at gmx.de>
>Release:        FreeBSD 7.2-RELEASE-p6 i386
>Organization:
>Environment:
System: FreeBSD 7.2-RELEASE-p6


>Description:
Outgoing states are not killed by authpf, since psk.psk_af is
overridden in authpf_kill_states with the No. of killed states
for incoming ipsrc.

Patch is only needed until code from OpenBSD >=200811 is merged
to FreeBSD since OpenBSD_4.4+ returns No. off killed states in 
psk.psk_killed.

The OpenBSD change is not documented in man page at the moment,
but you can find it out in the source (net/pfvar.h).
I found it this way by hacking snortsam.

Please see additional my PR 140369 to correct the man page for FreeBSD

>From man (4) pf:

DIOCKILLSTATES struct pfioc_state_kill *psk
     Remove matching entries from the state table. This ioctl returns
     the number of killed states in psk_af.


Here are the structs from FreeBSD and OpenBSD

FreeBSD:
struct pfioc_state_kill {
        /* XXX returns the number of states killed in psk_af */
        sa_family_t             psk_af;
        int                     psk_proto;
        struct pf_rule_addr     psk_src;
        struct pf_rule_addr     psk_dst;
        char                    psk_ifname[IFNAMSIZ];
};

OpenBSD_4.4/4.5:
struct pfioc_state_kill {
        struct pf_state_cmp     psk_pfcmp;
        sa_family_t             psk_af;
        int                     psk_proto;
        struct pf_rule_addr     psk_src;
        struct pf_rule_addr     psk_dst;
        char                    psk_ifname[IFNAMSIZ];
        char                    psk_label[PF_RULE_LABEL_SIZE];
        u_int                   psk_killed;
};


>How-To-Repeat:
>Fix:
The following patch safes the sa_family into a variable 'saf' and restores
psk.psk_af to this family after killing states from incoming ipsrc.



--- patch_authpf.c begins here ---
Index: base/stable/7/contrib/pf/authpf/authpf.c
===================================================================
--- base/stable/7/contrib/pf/authpf/authpf.c	(revision 203401)
+++ base/stable/7/contrib/pf/authpf/authpf.c	(working copy)
@@ -788,14 +788,15 @@ authpf_kill_states(void)
 {
 	struct pfioc_state_kill	psk;
 	struct pf_addr target;
+	sa_family_t saf;        /* safe AF_INET family */
 
 	memset(&psk, 0, sizeof(psk));
 	memset(&target, 0, sizeof(target));
 
 	if (inet_pton(AF_INET, ipsrc, &target.v4) == 1)
-		psk.psk_af = AF_INET;
+		psk.psk_af = saf = AF_INET;
 	else if (inet_pton(AF_INET6, ipsrc, &target.v6) == 1)
-		psk.psk_af = AF_INET6;
+		psk.psk_af = saf = AF_INET6;
 	else {
 		syslog(LOG_ERR, "inet_pton(%s) failed", ipsrc);
 		return;
@@ -809,6 +810,9 @@ authpf_kill_states(void)
 	if (ioctl(dev, DIOCKILLSTATES, &psk))
 		syslog(LOG_ERR, "DIOCKILLSTATES failed (%m)");
 
+	/* restore AF_INET, since it contains now the Nr. of killed states */
+	psk.psk_af = saf;
+
 	/* Kill all states to ipsrc */
 	memset(&psk.psk_src, 0, sizeof(psk.psk_src));
 	memcpy(&psk.psk_dst.addr.v.a.addr, &target,
--- patch_authpf.c ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list