Date: Thu, 8 May 2025 13:10:40 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: 3bb82353b528 - main - pf: reject hop-by-hop if it's not the first extension header Message-ID: <202505081310.548DAe8U047061@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=3bb82353b528e7e2a0815648d5be36c610b001f9 commit 3bb82353b528e7e2a0815648d5be36c610b001f9 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2025-05-06 09:18:27 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2025-05-08 13:10:24 +0000 pf: reject hop-by-hop if it's not the first extension header The pf fragment reassembly code accepted IPv6 hop-by-hop headers after fragment headers. Add an extra check that the hop-by-hop header is always the first extension header after the IPv6 header. Found by Antonios Atlasis; OK sthen@ mpi@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 17ea4b2bcd Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 2515c85c3eb7..2f69f36e2db3 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -9774,13 +9774,14 @@ 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 fraghdr_cnt = 0, rthdr_cnt = 0; + int hdr_cnt = 0, fraghdr_cnt = 0, 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 (;;) { + hdr_cnt++; switch (pd->proto) { case IPPROTO_FRAGMENT: if (fraghdr_cnt++) { @@ -9833,8 +9834,15 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) return (PF_DROP); } /* FALLTHROUGH */ - case IPPROTO_AH: case IPPROTO_HOPOPTS: + /* RFC2460 4.1: Hop-by-Hop only after IPv6 header */ + if (pd->proto == IPPROTO_HOPOPTS && hdr_cnt > 1) { + DPFPRINTF(PF_DEBUG_MISC, ("IPv6 hopopts not first")); + REASON_SET(reason, PFRES_IPOPTIONS); + return (PF_DROP); + } + /* FALLTHROUGH */ + case IPPROTO_AH: case IPPROTO_DSTOPTS: if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext), NULL, reason, AF_INET6)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505081310.548DAe8U047061>