git: 06c4372a2f1b - main - pf: do not reassemble atomic IPv6 fragments
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 13 Feb 2025 12:39:04 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=06c4372a2f1b4b4d5998b27a72df1b38a0238300
commit 06c4372a2f1b4b4d5998b27a72df1b38a0238300
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-02-10 14:10:57 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-02-13 12:38:44 +0000
pf: do not reassemble atomic IPv6 fragments
IPv6 atomic fragments must not go the reassembly queue, but be
processed immediately. Let pf step over an atomic fragment header
and handle the packet like an unfragmented.
OK mikeb@
Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, fd6d9d2982
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/netpfil/pf/pf.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 76f508b43750..65eb5736d43d 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -9580,7 +9580,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
struct ip6_ext ext;
struct ip6_rthdr rthdr;
uint32_t end;
- int rthdr_cnt = 0;
+ int fraghdr_cnt = 0, rthdr_cnt = 0;
pd->off += sizeof(struct ip6_hdr);
end = pd->off + ntohs(h->ip6_plen);
@@ -9589,7 +9589,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
for (;;) {
switch (pd->proto) {
case IPPROTO_FRAGMENT:
- if (pd->fragoff != 0) {
+ if (fraghdr_cnt++) {
DPFPRINTF(PF_DEBUG_MISC, ("IPv6 multiple fragment"));
REASON_SET(reason, PFRES_FRAG);
return (PF_DROP);
@@ -9605,10 +9605,14 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short fragment"));
return (PF_DROP);
}
- pd->fragoff = pd->off;
/* stop walking over non initial fragments */
- if (htons((frag.ip6f_offlg & IP6F_OFF_MASK)) != 0)
+ if (ntohs((frag.ip6f_offlg & IP6F_OFF_MASK)) != 0) {
+ pd->fragoff = pd->off;
return (PF_PASS);
+ }
+ /* RFC6946: reassemble only non atomic fragments */
+ if (frag.ip6f_offlg & IP6F_MORE_FRAG)
+ pd->fragoff = pd->off;
pd->off += sizeof(frag);
pd->proto = frag.ip6f_nxt;
break;