Date: Tue, 14 Jan 2025 10:38:01 GMT From: Kristof Provost <kp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 5466aca1536e - main - pf: minor fixes for pf_walk_header6() Message-ID: <202501141038.50EAc1ui048459@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=5466aca1536e45b2d327ff9ae232700ea01f30e8 commit 5466aca1536e45b2d327ff9ae232700ea01f30e8 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2025-01-09 13:39:20 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2025-01-14 08:54:20 +0000 pf: minor fixes for pf_walk_header6() - Fragment offset is in network byte order. - Check for legal short fragments before calling pf_pull_hdr() to avoid bogus reason accounting. - When checking wether the protocol header is within the fragment, count the IPv6 payload length relative to the end of the IPv6 header. ok henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 3230e62590 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 11b6be239ca7..053b0b2ccb31 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -9720,9 +9720,11 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) struct ip6_frag frag; struct ip6_ext ext; struct ip6_rthdr rthdr; + uint32_t end; int rthdr_cnt = 0; pd->off += sizeof(struct ip6_hdr); + end = pd->off + ntohs(h->ip6_plen); pd->fragoff = pd->extoff = pd->jumbolen = 0; pd->proto = h->ip6_nxt; for (;;) { @@ -9746,7 +9748,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) } pd->fragoff = pd->off; /* stop walking over non initial fragments */ - if ((frag.ip6f_offlg & IP6F_OFF_MASK) != 0) + if (htons((frag.ip6f_offlg & IP6F_OFF_MASK)) != 0) return (PF_PASS); pd->off += sizeof(frag); pd->proto = frag.ip6f_nxt; @@ -9757,14 +9759,14 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); } + /* fragments may be short */ + if (pd->fragoff != 0 && end < pd->off + sizeof(rthdr)) { + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; + return (PF_PASS); + } if (!pf_pull_hdr(pd->m, pd->off, &rthdr, sizeof(rthdr), NULL, reason, AF_INET6)) { - /* fragments may be short */ - if (pd->fragoff != 0) { - pd->off = pd->fragoff; - pd->proto = IPPROTO_FRAGMENT; - return (PF_PASS); - } DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short rthdr")); return (PF_DROP); } @@ -9779,15 +9781,15 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) case IPPROTO_DSTOPTS: if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext), NULL, reason, AF_INET6)) { - /* fragments may be short */ - if (pd->fragoff != 0) { - pd->off = pd->fragoff; - pd->proto = IPPROTO_FRAGMENT; - return (PF_PASS); - } DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short exthdr")); return (PF_DROP); } + /* fragments may be short */ + if (pd->fragoff != 0 && end < pd->off + sizeof(ext)) { + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; + return (PF_PASS); + } /* reassembly needs the ext header before the frag */ if (pd->fragoff == 0) pd->extoff = pd->off; @@ -9815,7 +9817,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) case IPPROTO_SCTP: case IPPROTO_ICMPV6: /* fragments may be short, ignore inner header then */ - if (pd->fragoff != 0 && ntohs(h->ip6_plen) < pd->off + + if (pd->fragoff != 0 && end < pd->off + (pd->proto == IPPROTO_TCP ? sizeof(struct tcphdr) : pd->proto == IPPROTO_UDP ? sizeof(struct udphdr) : pd->proto == IPPROTO_SCTP ? sizeof(struct sctphdr) :
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202501141038.50EAc1ui048459>