Skip site navigation (1)Skip section navigation (2)
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>