git: 7b033960e15a - main - pf: stricter address family checks in icmp-in-icmp

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 10 Oct 2024 12:37:17 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=7b033960e15a998a388b1e4e84be9169b7762470

commit 7b033960e15a998a388b1e4e84be9169b7762470
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-09-30 12:31:13 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-10-10 12:10:39 +0000

    pf: stricter address family checks in icmp-in-icmp
    
    If ipv4+icmp6 or ipv6+icmp packets were embedded into an icmp
    payload, we missed to drop them.  While there, also add a reason
    to the corresponding check in pf_test().
    ok mcbride@ claudio@
    
    Obtained from:  OpenBSD, bluhm <bluhm@openbsd.org>, 7ce93f3346
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D46929
---
 sys/netpfil/pf/pf.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index aa63c2c1d390..891c490a0b1e 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -7342,6 +7342,11 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
 		case IPPROTO_ICMP: {
 			struct icmp	*iih = &pd2.hdr.icmp;
 
+			if (pd2.af != AF_INET) {
+				REASON_SET(reason, PFRES_NORM);
+				return (PF_DROP);
+			}
+
 			if (!pf_pull_hdr(m, off2, iih, ICMP_MINLEN,
 			    NULL, reason, pd2.af)) {
 				DPFPRINTF(PF_DEBUG_MISC,
@@ -7400,6 +7405,11 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
 		case IPPROTO_ICMPV6: {
 			struct icmp6_hdr	*iih = &pd2.hdr.icmp6;
 
+			if (pd2.af != AF_INET6) {
+				REASON_SET(reason, PFRES_NORM);
+				return (PF_DROP);
+			}
+
 			if (!pf_pull_hdr(m, off2, iih,
 			    sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
 				DPFPRINTF(PF_DEBUG_MISC,
@@ -9201,6 +9211,7 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
 	case IPPROTO_ICMP: {
 		if (af != AF_INET) {
 			action = PF_DROP;
+			REASON_SET(&reason, PFRES_NORM);
 			DPFPRINTF(PF_DEBUG_MISC,
 			    ("dropping IPv6 packet with ICMPv4 payload"));
 			goto done;
@@ -9220,6 +9231,7 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
 	case IPPROTO_ICMPV6: {
 		if (af != AF_INET6) {
 			action = PF_DROP;
+			REASON_SET(&reason, PFRES_NORM);
 			DPFPRINTF(PF_DEBUG_MISC,
 			    ("pf: dropping IPv4 packet with ICMPv6 payload\n"));
 			goto done;