Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Jun 2025 11:17:12 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: dda88af8fa4e - main - pf: limit how many headers we look at
Message-ID:  <202506061117.556BHCOo083639@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=dda88af8fa4eb1455a6e899434936c4ddeaf526d

commit dda88af8fa4eb1455a6e899434936c4ddeaf526d
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-05-26 09:55:12 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-06-06 11:16:00 +0000

    pf: limit how many headers we look at
    
    Limit the nested header chain for IPv6 extensions headers and for
    authentication headers in the IPv4 case.  This prevents spending
    excessive cpu time on crafted packets.
    OK henning@
    
    Obtained from:  OpenBSD, bluhm <bluhm@openbsd.org>, 2e5bc81177
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D50659
---
 sys/netpfil/pf/pf.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 0cfb728c3eb5..f1b04a96590b 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -180,6 +180,8 @@ VNET_DEFINE(u_int32_t,			 ticket_altqs_inactive);
 VNET_DEFINE(int,			 altqs_inactive_open);
 VNET_DEFINE(u_int32_t,			 ticket_pabuf);
 
+static const int			 PF_HDR_LIMIT = 20;	/* arbitrary limit */
+
 VNET_DEFINE(SHA512_CTX,			 pf_tcp_secret_ctx);
 #define	V_pf_tcp_secret_ctx		 VNET(pf_tcp_secret_ctx)
 VNET_DEFINE(u_char,			 pf_tcp_secret[16]);
@@ -9698,6 +9700,7 @@ pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
 {
 	struct ah	 ext;
 	u_int32_t	 hlen, end;
+	int		 hdr_cnt;
 
 	hlen = h->ip_hl << 2;
 	if (hlen < sizeof(struct ip) || hlen > ntohs(h->ip_len)) {
@@ -9710,7 +9713,7 @@ pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
 	/* stop walking over non initial fragments */
 	if ((h->ip_off & htons(IP_OFFMASK)) != 0)
 		return (PF_PASS);
-	for (;;) {
+	for (hdr_cnt = 0; hdr_cnt < PF_HDR_LIMIT; hdr_cnt++) {
 		switch (pd->proto) {
 		case IPPROTO_AH:
 			/* fragments may be short */
@@ -9729,6 +9732,9 @@ pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
 			return (PF_PASS);
 		}
 	}
+	DPFPRINTF(PF_DEBUG_MISC, ("IPv4 nested authentication header limit"));
+	REASON_SET(reason, PFRES_IPOPTIONS);
+	return (PF_DROP);
 }
 
 #ifdef INET6
@@ -9801,14 +9807,13 @@ 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			 hdr_cnt = 0, fraghdr_cnt = 0, rthdr_cnt = 0;
+	int			 hdr_cnt, 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++;
+	for (hdr_cnt = 0; hdr_cnt < PF_HDR_LIMIT; hdr_cnt++) {
 		switch (pd->proto) {
 		case IPPROTO_FRAGMENT:
 			if (fraghdr_cnt++) {
@@ -9863,7 +9868,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
 			/* FALLTHROUGH */
 		case IPPROTO_HOPOPTS:
 			/* RFC2460 4.1:  Hop-by-Hop only after IPv6 header */
-			if (pd->proto == IPPROTO_HOPOPTS && hdr_cnt > 1) {
+			if (pd->proto == IPPROTO_HOPOPTS && hdr_cnt > 0) {
 				DPFPRINTF(PF_DEBUG_MISC, ("IPv6 hopopts not first"));
 				REASON_SET(reason, PFRES_IPOPTIONS);
 				return (PF_DROP);
@@ -9922,6 +9927,9 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
 			return (PF_PASS);
 		}
 	}
+	DPFPRINTF(PF_DEBUG_MISC, ("IPv6 nested extension header limit"));
+	REASON_SET(reason, PFRES_IPOPTIONS);
+	return (PF_DROP);
 }
 #endif /* INET6 */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506061117.556BHCOo083639>