git: 5a79138b3884 - main - pf: fix quoted ip packet length for af-to

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 06 Feb 2025 14:00:16 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=5a79138b3884d9c5ef91d265f8c605f930cd113e

commit 5a79138b3884d9c5ef91d265f8c605f930cd113e
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-02-03 10:16:11 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-02-06 14:00:05 +0000

    pf: fix quoted ip packet length for af-to
    
    With address family translation, the ip length of the quoted ip
    packet within the icmp error packet was wrong.  Fix this by using
    the pd2.tot_len of the inner packet and substract the old header's
    length.
    OK mikeb@ henning@
    
    Obtained from:  OpenBSD, bluhm <bluhm@openbsd.org>, 3d0247e0e8
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/netpfil/pf/pf.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index d78978a75317..1cfd1a11db53 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3566,8 +3566,6 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
 	olen = pd2->off - off;
 	/* new header */
 	hlen = naf == AF_INET ? sizeof(*ip4) : sizeof(*ip6);
-	/* data lenght */
-	mlen = m->m_pkthdr.len - pd2->off;
 
 	/* trim old header */
 	m_adj(n, olen);
@@ -3584,7 +3582,7 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
 		bzero(ip4, sizeof(*ip4));
 		ip4->ip_v = IPVERSION;
 		ip4->ip_hl = sizeof(*ip4) >> 2;
-		ip4->ip_len = htons(sizeof(*ip4) + mlen);
+		ip4->ip_len = htons(sizeof(*ip4) + pd2->tot_len - olen);
 		ip_fillid(ip4);
 		ip4->ip_off = htons(IP_DF);
 		ip4->ip_ttl = pd2->ttl;
@@ -3600,7 +3598,7 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
 		ip6 = mtod(n, struct ip6_hdr *);
 		bzero(ip6, sizeof(*ip6));
 		ip6->ip6_vfc = IPV6_VERSION;
-		ip6->ip6_plen = htons(mlen);
+		ip6->ip6_plen = htons(pd2->tot_len - olen);
 		if (pd2->proto == IPPROTO_ICMP)
 			ip6->ip6_nxt = IPPROTO_ICMPV6;
 		else
@@ -7936,6 +7934,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
 			pd2.off = ipoff2 + (h2.ip_hl << 2);
 
 			pd2.proto = h2.ip_p;
+			pd2.tot_len = ntohs(h2.ip_len);
 			pd2.src = (struct pf_addr *)&h2.ip_src;
 			pd2.dst = (struct pf_addr *)&h2.ip_dst;
 			pd2.ip_sum = &h2.ip_sum;
@@ -7956,6 +7955,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
 			if (pf_walk_header6(&pd2, &h2_6, reason) != PF_PASS)
 				return (PF_DROP);
 
+			pd2.tot_len = ntohs(h2_6.ip6_plen) +
+			    sizeof(struct ip6_hdr);
 			pd2.src = (struct pf_addr *)&h2_6.ip6_src;
 			pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
 			pd2.ip_sum = NULL;