aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2025-01-09 13:11:11 +0000
committerKristof Provost <kp@FreeBSD.org>2025-01-14 08:54:20 +0000
commit3b79f6d2d39405bcac395dc036ceb6f8fd09ce99 (patch)
tree50d69b6ff14c0973e283bf45395cf3fc4b23eb58
parent1941d370bf89ea9a1c3aab5ce33e04d6ba0f635d (diff)
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")
-rw-r--r--sys/netpfil/pf/pf_norm.c30
1 files 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);