git: 130b5e3f536e - main - pf: be more strict about IPv6 fragments
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 09 May 2025 22:16:17 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=130b5e3f536e322f3e96ad1d786cbac3592f10c3 commit 130b5e3f536e322f3e96ad1d786cbac3592f10c3 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2025-05-08 14:52:53 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2025-05-09 20:49:28 +0000 pf: be more strict about IPv6 fragments Follow RFC 5722 more strictly when handling overlapping fragments in pf. Drop the whole fragment state if IPv6 fragments appear which have invalid length or fragment-offset or more-fragment-bit. In IPv4 they are considered invalid and just dropped like before. Found by Antonios Atlasis; OK sashan@ sthen@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, f0f63321f2 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf_norm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index c77895d1829d..8157ea556591 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -603,16 +603,16 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, /* Non terminal fragments must have more fragments flag. */ if (frent->fe_off + frent->fe_len < total && !frent->fe_mff) - goto bad_fragment; + goto free_ipv6_fragment; /* Check if we saw the last fragment already. */ if (!TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_mff) { if (frent->fe_off + frent->fe_len > total || (frent->fe_off + frent->fe_len == total && frent->fe_mff)) - goto bad_fragment; + goto free_ipv6_fragment; } else { if (frent->fe_off + frent->fe_len == total && !frent->fe_mff) - goto bad_fragment; + goto free_ipv6_fragment; } /* Find neighbors for newly inserted fragment */ @@ -680,6 +680,9 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, return (frag); +free_ipv6_fragment: + if (frag->fr_af == AF_INET) + goto bad_fragment; free_fragment: /* * RFC 5722, Errata 3089: When reassembling an IPv6 datagram, if one