Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Oct 2024 12:37:15 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: 7d0f8cd93bce - main - pf: ensure that we won't enter an endless loop
Message-ID:  <202410101237.49ACbFWA006101@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=7d0f8cd93bce786728a1fff8b2e2184c8e48f3b2

commit 7d0f8cd93bce786728a1fff8b2e2184c8e48f3b2
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-09-26 15:53:53 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-10-10 12:10:39 +0000

    pf: ensure that we won't enter an endless loop
    
    ensure that we won't enter an endless loop while iterating over
    an address pool.  problem found and solution tested by claudio.
    ok claudio, henning, "reads fine" to zinke
    
    Obtained from:  OpenBSD, mikeb <mikeb@openbsd.org>, e4fc4bddb9
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D46927
---
 sys/netpfil/pf/pf_table.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index 690cb6d9ab90..77bd466ec2b3 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -2245,7 +2245,7 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
 	struct pf_addr		 addr, cur, mask, umask_addr;
 	union sockaddr_union	 uaddr, umask;
 	struct pfr_kentry	*ke, *ke2 = NULL;
-	int			 idx = -1, use_counter = 0;
+	int			 startidx, idx = -1, loop = 0, use_counter = 0;
 
 	MPASS(pidx != NULL);
 	MPASS(counter != NULL);
@@ -2272,18 +2272,29 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
 		use_counter = 1;
 	if (idx < 0)
 		idx = 0;
+	startidx = idx;
 
 _next_block:
-	ke = pfr_kentry_byidx(kt, idx, af);
-	if (ke == NULL) {
+	if (loop && startidx == idx) {
 		pfr_kstate_counter_add(&kt->pfrkt_nomatch, 1);
 		return (1);
 	}
+
+	ke = pfr_kentry_byidx(kt, idx, af);
+	if (ke == NULL) {
+		/* we don't have this idx, try looping */
+		if (loop || (ke = pfr_kentry_byidx(kt, 0, af)) == NULL) {
+			pfr_kstate_counter_add(&kt->pfrkt_nomatch, 1);
+			return (1);
+		}
+		idx = 0;
+		loop++;
+	}
 	pfr_prepare_network(&umask, af, ke->pfrke_net);
 	pfr_sockaddr_to_pf_addr(&ke->pfrke_sa, &cur);
 	pfr_sockaddr_to_pf_addr(&umask, &mask);
 
-	if (use_counter) {
+	if (use_counter && !PF_AZERO(counter, af)) {
 		/* is supplied address within block? */
 		if (!PF_MATCHA(0, &cur, &mask, counter, af)) {
 			/* no, go to next block in table */



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