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)