Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Feb 2025 09:38:46 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 30ab6e823c59 - main - pf: fix anchor quick with nested anchors
Message-ID:  <202502120938.51C9ck8Q037468@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=30ab6e823c5914a0ecc296d766b8a92222724d09

commit 30ab6e823c5914a0ecc296d766b8a92222724d09
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-02-05 15:41:41 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-02-12 08:29:09 +0000

    pf: fix anchor quick with nested anchors
    
    We lost the quick flag as soon as we stepped into a child anchor.
    Simplify the logic, get rid of the match flag in the anchor stack, just
    use the match variable we already had (and used in a boolean style) to track
    the nest level we had a match at. When a child anchor had a match we also
    have a match in the current anchor, so update the match level accordingly,
    and thus correctly honour the quick flag.
    Reported by, along with the right idea on how to fix this, by Sean Gallagher
    \sean at teletech.com.au/, who also helped testing the fix. ok ryan & benno
    
    Obtained from:  OpenBSD, henning <henning@openbsd.org>, 32a028bff7
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pfvar.h        |  2 +-
 sys/netpfil/pf/pf.c    | 30 ++++++++----------------------
 sys/netpfil/pf/pf_lb.c |  2 +-
 3 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 5ef7957f4fa0..65be1a0ce19b 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2646,7 +2646,7 @@ void			 pf_print_host(struct pf_addr *, u_int16_t, sa_family_t);
 
 void			 pf_step_into_anchor(struct pf_kanchor_stackframe *, int *,
 			    struct pf_kruleset **, int, struct pf_krule **,
-			    struct pf_krule **, int *);
+			    struct pf_krule **);
 int			 pf_step_out_of_anchor(struct pf_kanchor_stackframe *, int *,
 			    struct pf_kruleset **, int, struct pf_krule **,
 			    struct pf_krule **, int *);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 9963dc728302..79e50be6cd13 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -4569,15 +4569,12 @@ struct pf_kanchor_stackframe {
 
 void
 pf_step_into_anchor(struct pf_kanchor_stackframe *stack, int *depth,
-    struct pf_kruleset **rs, int n, struct pf_krule **r, struct pf_krule **a,
-    int *match)
+    struct pf_kruleset **rs, int n, struct pf_krule **r, struct pf_krule **a)
 {
 	struct pf_kanchor_stackframe	*f;
 
 	PF_RULES_RASSERT();
 
-	if (match)
-		*match = 0;
 	if (*depth >= PF_ANCHOR_STACKSIZE) {
 		printf("%s: anchor stack overflow on %s\n",
 		    __func__, (*r)->anchor->name);
@@ -4620,19 +4617,6 @@ pf_step_out_of_anchor(struct pf_kanchor_stackframe *stack, int *depth,
 		f = stack + *depth - 1;
 		fr = PF_ANCHOR_RULE(f);
 		if (f->child != NULL) {
-			/*
-			 * This block traverses through
-			 * a wildcard anchor.
-			 */
-			if (match != NULL && *match) {
-				/*
-				 * If any of "*" matched, then
-				 * "foo/ *" matched, mark frame
-				 * appropriately.
-				 */
-				PF_ANCHOR_SET_MATCH(f);
-				*match = 0;
-			}
 			f->child = RB_NEXT(pf_kanchor_node,
 			    &fr->anchor->children, f->child);
 			if (f->child != NULL) {
@@ -4648,8 +4632,11 @@ pf_step_out_of_anchor(struct pf_kanchor_stackframe *stack, int *depth,
 		if (*depth == 0 && a != NULL)
 			*a = NULL;
 		*rs = f->rs;
-		if (PF_ANCHOR_MATCH(f) || (match != NULL && *match))
-			quick = fr->quick;
+		if (match != NULL && *match > *depth) {
+			*match = *depth;
+			if (f->r->quick)
+				quick = 1;
+		}
 		*r = TAILQ_NEXT(fr, entries);
 	} while (*r == NULL);
 
@@ -5831,7 +5818,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm,
 					PFLOG_PACKET(r->action, PFRES_MATCH, r,
 					    a, ruleset, pd, 1);
 			} else {
-				match = 1;
+				match = asd;
 				*rm = r;
 				*am = a;
 				*rsm = ruleset;
@@ -5844,8 +5831,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm,
 			r = TAILQ_NEXT(r, entries);
 		} else
 			pf_step_into_anchor(anchor_stack, &asd,
-			    &ruleset, PF_RULESET_FILTER, &r, &a,
-			    &match);
+			    &ruleset, PF_RULESET_FILTER, &r, &a);
 nextrule:
 		if (r == NULL && pf_step_out_of_anchor(anchor_stack, &asd,
 		    &ruleset, PF_RULESET_FILTER, &r, &a, &match))
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index 6251ddee7d19..23c7ad1c0a66 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -211,7 +211,7 @@ pf_match_translation(struct pf_pdesc *pd,
 				break;
 			} else
 				pf_step_into_anchor(anchor_stack, &asd,
-				    &ruleset, rs_num, &r, NULL, NULL);
+				    &ruleset, rs_num, &r, NULL);
 		}
 		if (r == NULL)
 			pf_step_out_of_anchor(anchor_stack, &asd, &ruleset,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502120938.51C9ck8Q037468>