git: 589c67771edf - main - pf: drop packets if pullup fails

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 19 Sep 2024 20:21:18 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=589c67771edf71fbc14bd33f6b8b90f4f327ad25

commit 589c67771edf71fbc14bd33f6b8b90f4f327ad25
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-09-03 08:45:37 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-09-19 20:20:13 +0000

    pf: drop packets if pullup fails
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D46587
---
 sys/netpfil/pf/pf.c | 39 ++++++++++++++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 59db6fd96953..f340c76da40e 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -8589,8 +8589,11 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 			struct tcphdr *th = &pd->hdr.tcp;
 
 			if (!pf_pull_hdr(m, *off, th, sizeof(*th), action,
-				reason, AF_INET))
+				reason, AF_INET)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
+			}
 			*hdrlen = sizeof(*th);
 			pd->p_len = pd->tot_len - *off - (th->th_off << 2);
 			pd->sport = &th->th_sport;
@@ -8601,8 +8604,11 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 			struct udphdr *uh = &pd->hdr.udp;
 
 			if (!pf_pull_hdr(m, *off, uh, sizeof(*uh), action,
-				reason, AF_INET))
+				reason, AF_INET)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
+			}
 			*hdrlen = sizeof(*uh);
 			if (uh->uh_dport == 0 ||
 			    ntohs(uh->uh_ulen) > m->m_pkthdr.len - *off ||
@@ -8618,6 +8624,8 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 		case IPPROTO_SCTP: {
 			if (!pf_pull_hdr(m, *off, &pd->hdr.sctp, sizeof(pd->hdr.sctp),
 			    action, reason, AF_INET)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
 			}
 			*hdrlen = sizeof(pd->hdr.sctp);
@@ -8639,8 +8647,11 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 		}
 		case IPPROTO_ICMP: {
 			if (!pf_pull_hdr(m, *off, &pd->hdr.icmp, ICMP_MINLEN,
-				action, reason, AF_INET))
+				action, reason, AF_INET)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
+			}
 			*hdrlen = ICMP_MINLEN;
 			break;
 		}
@@ -8738,8 +8749,11 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 			struct tcphdr *th = &pd->hdr.tcp;
 
 			if (!pf_pull_hdr(m, *off, th, sizeof(*th), action,
-				reason, AF_INET6))
+				reason, AF_INET6)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
+			}
 			*hdrlen = sizeof(*th);
 			pd->p_len = pd->tot_len - *off - (th->th_off << 2);
 			pd->sport = &th->th_sport;
@@ -8750,8 +8764,11 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 			struct udphdr *uh = &pd->hdr.udp;
 
 			if (!pf_pull_hdr(m, *off, uh, sizeof(*uh), action,
-				reason, AF_INET6))
+				reason, AF_INET6)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
+			}
 			*hdrlen = sizeof(*uh);
 			if (uh->uh_dport == 0 ||
 			    ntohs(uh->uh_ulen) > m->m_pkthdr.len - *off ||
@@ -8767,6 +8784,8 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 		case IPPROTO_SCTP: {
 			if (!pf_pull_hdr(m, *off, &pd->hdr.sctp, sizeof(pd->hdr.sctp),
 			    action, reason, AF_INET6)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
 			}
 			*hdrlen = sizeof(pd->hdr.sctp);
@@ -8790,8 +8809,11 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 			size_t icmp_hlen = sizeof(struct icmp6_hdr);
 
 			if (!pf_pull_hdr(m, *off, &pd->hdr.icmp6, icmp_hlen,
-				action, reason, AF_INET6))
+				action, reason, AF_INET6)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
+			}
 			/* ICMP headers we look further into to match state */
 			switch (pd->hdr.icmp6.icmp6_type) {
 			case MLD_LISTENER_QUERY:
@@ -8805,8 +8827,11 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
 			}
 			if (icmp_hlen > sizeof(struct icmp6_hdr) &&
 			    !pf_pull_hdr(m, *off, &pd->hdr.icmp6, icmp_hlen,
-				action, reason, AF_INET6))
+				action, reason, AF_INET6)) {
+				*action = PF_DROP;
+				REASON_SET(reason, PFRES_SHORT);
 				return (-1);
+			}
 			*hdrlen = icmp_hlen;
 			break;
 		}