diff options
author | Kristof Provost <kp@FreeBSD.org> | 2025-01-09 13:11:11 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2025-01-14 08:54:20 +0000 |
commit | 3b79f6d2d39405bcac395dc036ceb6f8fd09ce99 (patch) | |
tree | 50d69b6ff14c0973e283bf45395cf3fc4b23eb58 | |
parent | 1941d370bf89ea9a1c3aab5ce33e04d6ba0f635d (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.c | 30 |
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); |