git: 423b1069af74 - main - pf: ensure mbufs are writable
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 11 Sep 2024 11:18:27 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=423b1069af744e717bafb3dbd0764926e2aabd88
commit 423b1069af744e717bafb3dbd0764926e2aabd88
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-09-10 20:16:13 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-09-11 11:17:48 +0000
pf: ensure mbufs are writable
Ensure that we can modify mbufs before we start processing them. There are a
number of paths where pf will m_copyback() or otherwise modify a packet. Ensure
that this is safe to do.
For example, ip6_forward() will m_copym() the packet before handing it to the
output pfil hook. This results in a non-writable mbuf, which would trigger
assertion failures (see previous commit).
Reviewed by: glebius (previous version)
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D46628
---
sys/netpfil/pf/pf.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 70220dda935e..1535843d81b1 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -8415,6 +8415,12 @@ pf_test_eth(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0,
if (m->m_flags & M_SKIP_FIREWALL)
return (PF_PASS);
+ if (__predict_false(! M_WRITABLE(*m0))) {
+ m = *m0 = m_unshare(*m0, M_NOWAIT);
+ if (*m0 == NULL)
+ return (PF_DROP);
+ }
+
/* Stateless! */
return (pf_test_eth_rule(dir, kif, m0));
}
@@ -8553,6 +8559,12 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0,
return (PF_PASS);
}
+ if (__predict_false(! M_WRITABLE(*m0))) {
+ m = *m0 = m_unshare(*m0, M_NOWAIT);
+ if (*m0 == NULL)
+ return (PF_DROP);
+ }
+
memset(&pd, 0, sizeof(pd));
TAILQ_INIT(&pd.sctp_multihome_jobs);
if (default_actions != NULL)
@@ -9147,6 +9159,12 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
return (PF_DROP);
}
+ if (__predict_false(! M_WRITABLE(*m0))) {
+ m = *m0 = m_unshare(*m0, M_NOWAIT);
+ if (*m0 == NULL)
+ return (PF_DROP);
+ }
+
memset(&pd, 0, sizeof(pd));
TAILQ_INIT(&pd.sctp_multihome_jobs);
if (default_actions != NULL)