git: 3b79f6d2d394 - main - pf: do not keep state when dropping overlapping IPv6 fragments

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Tue, 14 Jan 2025 10:37:59 UTC
The branch main has been updated by kp:

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

commit 3b79f6d2d39405bcac395dc036ceb6f8fd09ce99
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-01-09 13:11:11 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-01-14 08:54:20 +0000

    pf: do not keep state when dropping overlapping IPv6 fragments
    
    ok sperreault@
    
    Obtained from:  OpenBSD, bluhm <bluhm@openbsd.org>, cd45765685
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/netpfil/pf/pf_norm.c | 30 ++++++++----------------------
 1 file changed, 8 insertions(+), 22 deletions(-)

diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index 45e56edc34fe..9f1eaf7c4d76 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -606,15 +606,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent,
 		return (frag);
 	}
 
-	if (TAILQ_EMPTY(&frag->fr_queue)) {
-		/*
-		 * Overlapping IPv6 fragments have been detected.  Do not
-		 * reassemble packet but also drop future fragments.
-		 * This will be done for this ident/src/dst combination
-		 * until fragment queue timeout.
-		 */
-		goto drop_fragment;
-	}
+	KASSERT(!TAILQ_EMPTY(&frag->fr_queue), ("!TAILQ_EMPTY()->fr_queue"));
 
 	/* Remember maximum fragment len for refragmentation. */
 	if (frent->fe_len > frag->fr_maxlen)
@@ -651,7 +643,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent,
 		uint16_t precut;
 
 		if (frag->fr_af == AF_INET6)
-			goto flush_fragentries;
+			goto free_fragment;
 
 		precut = prev->fe_off + prev->fe_len - frent->fe_off;
 		if (precut >= frent->fe_len) {
@@ -715,21 +707,15 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent,
 
 	return (frag);
 
-flush_fragentries:
+free_fragment:
 	/*
-	 * RFC5722:  When reassembling an IPv6 datagram, if one or
-	 * more its constituent fragments is determined to be an
-	 * overlapping fragment, the entire datagram (and any constituent
-	 * fragments, including those not yet received) MUST be
-	 * silently discarded.
+	 * RFC 5722, Errata 3089:  When reassembling an IPv6 datagram, if one
+	 * or more its constituent fragments is determined to be an overlapping
+	 * fragment, the entire datagram (and any constituent fragments) MUST
+	 * be silently discarded.
 	 */
 	DPFPRINTF(("flush overlapping fragments\n"));
-	while ((prev = TAILQ_FIRST(&frag->fr_queue)) != NULL) {
-		TAILQ_REMOVE(&frag->fr_queue, prev, fr_next);
-
-		m_freem(prev->fe_m);
-		uma_zfree(V_pf_frent_z, prev);
-	}
+	pf_free_fragment(frag);
 
 bad_fragment:
 	REASON_SET(reason, PFRES_FRAG);