From c1746f11b0c8af70eecbe03fcd247444643d7685 Mon Sep 17 00:00:00 2001 From: bluhm Date: Mon, 10 Sep 2018 12:47:02 +0000 Subject: [PATCH] During fragment reassembly, mbuf chains with packet headers were created. Add a new function m_removehdr() do convert packet header mbufs within the chain to regular mbufs. Assert that the mbuf at the beginning of the chain has a packet header. found by Maxime Villard in NetBSD; from markus@; OK claudio@ --- share/man/man9/mbuf.9 | 17 ++++++++++++++--- sys/kern/uipc_mbuf.c | 33 +++++++++++++++++++++++---------- sys/net/pf_norm.c | 11 ++++++++--- sys/netinet/ip_input.c | 8 +++++--- sys/netinet6/frag6.c | 7 +++++-- sys/sys/mbuf.h | 3 ++- 6 files changed, 57 insertions(+), 22 deletions(-) diff --git a/share/man/man9/mbuf.9 b/share/man/man9/mbuf.9 index d70a070fc0a..d08f1d246e0 100644 --- a/share/man/man9/mbuf.9 +++ b/share/man/man9/mbuf.9 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mbuf.9,v 1.111 2018/02/11 00:27:10 dlg Exp $ +.\" $OpenBSD: mbuf.9,v 1.112 2018/09/10 12:47:02 bluhm Exp $ .\" .\" Copyright (c) 2001 Jean-Jacques Bernard-Gundol .\" All rights reserved. @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 11 2018 $ +.Dd $Mdocdate: September 10 2018 $ .Dt MGET 9 .Os .Sh NAME @@ -35,6 +35,7 @@ .Nm MGET , .Nm m_getclr , .Nm m_gethdr , +.Nm m_removehdr , .Nm m_resethdr , .Nm MGETHDR , .Nm m_prepend , @@ -79,6 +80,8 @@ .Ft struct mbuf * .Fn m_getclr "int how" "int type" .Ft void +.Fn m_removehdr "struct mbuf *m" +.Ft void .Fn m_resethdr "struct mbuf *m" .Ft struct mbuf * .Fn m_gethdr "int how" "int type" @@ -486,11 +489,19 @@ See .Fn m_get for a description of .Fa how . +.It Fn m_removehdr "struct mbuf *m" +Convert a mbuf with packet header to one without. +Delete all +.Xr pf 4 +data and all tags attached to a +.Fa mbuf . +Keep the data and mbuf chain, clear the packet header. .It Fn m_resethdr "struct mbuf *m" -Deletes all +Delete all .Xr pf 4 data and all tags attached to a .Fa mbuf . +Keep the data and mbuf chain, initialize the packet header. .It Fn m_gethdr "int how" "int type" Return a pointer to an mbuf of the type specified after initializing it to contain a packet header. diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 5bb5c624978..2dda4b56292 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.256 2018/03/18 21:25:14 deraadt Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.257 2018/09/10 12:47:02 bluhm Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -291,15 +291,9 @@ m_inithdr(struct mbuf *m) return (m); } -void -m_resethdr(struct mbuf *m) +static inline void +m_clearhdr(struct mbuf *m) { - int len = m->m_pkthdr.len; - u_int8_t loopcnt = m->m_pkthdr.ph_loopcnt; - - KASSERT(m->m_flags & M_PKTHDR); - m->m_flags &= (M_EXT|M_PKTHDR|M_EOR|M_EXTWR|M_ZEROIZE); - /* delete all mbuf tags to reset the state */ m_tag_delete_chain(m); @@ -307,8 +301,27 @@ m_resethdr(struct mbuf *m) pf_mbuf_unlink_state_key(m); #endif /* NPF > 0 */ - /* like m_inithdr(), but keep any associated data and mbufs */ memset(&m->m_pkthdr, 0, sizeof(m->m_pkthdr)); +} + +void +m_removehdr(struct mbuf *m) +{ + KASSERT(m->m_flags & M_PKTHDR); + m_clearhdr(m); + m->m_flags &= ~M_PKTHDR; +} + +void +m_resethdr(struct mbuf *m) +{ + int len = m->m_pkthdr.len; + u_int8_t loopcnt = m->m_pkthdr.ph_loopcnt; + + KASSERT(m->m_flags & M_PKTHDR); + m->m_flags &= (M_EXT|M_PKTHDR|M_EOR|M_EXTWR|M_ZEROIZE); + m_clearhdr(m); + /* like m_inithdr(), but keep any associated data and mbufs */ m->m_pkthdr.pf.prio = IFQ_DEFPRIO; m->m_pkthdr.len = len; m->m_pkthdr.ph_loopcnt = loopcnt; diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c index a328c9be7cd..d60dd43442b 100644 --- a/sys/net/pf_norm.c +++ b/sys/net/pf_norm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_norm.c,v 1.214 2018/09/10 11:37:26 bluhm Exp $ */ +/* $OpenBSD: pf_norm.c,v 1.215 2018/09/10 12:47:02 bluhm Exp $ */ /* * Copyright 2001 Niels Provos @@ -743,6 +743,7 @@ pf_join_fragment(struct pf_fragment *frag) m_adj(m2, frent->fe_len - m2->m_pkthdr.len); pool_put(&pf_frent_pl, frent); pf_nfrents--; + m_removehdr(m2); m_cat(m, m2); } @@ -805,8 +806,10 @@ pf_reassemble(struct mbuf **m0, int dir, u_short *reason) m = *m0 = pf_join_fragment(frag); frag = NULL; - if (m->m_flags & M_PKTHDR) { + { int plen = 0; + + KASSERT(m->m_flags & M_PKTHDR); for (m = *m0; m; m = m->m_next) plen += m->m_len; m = *m0; @@ -904,8 +907,10 @@ pf_reassemble6(struct mbuf **m0, struct ip6_frag *fraghdr, if (frag6_deletefraghdr(m, hdrlen) != 0) goto fail; - if (m->m_flags & M_PKTHDR) { + { int plen = 0; + + KASSERT(m->m_flags & M_PKTHDR); for (m = *m0; m; m = m->m_next) plen += m->m_len; m = *m0; diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 4585b7f8b06..3e9bab33b36 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.338 2018/07/10 11:34:12 mpi Exp $ */ +/* $OpenBSD: ip_input.c,v 1.339 2018/09/10 12:47:02 bluhm Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -947,6 +947,7 @@ insert: nq = LIST_NEXT(q, ipqe_q); pool_put(&ipqent_pool, q); ip_frags--; + m_removehdr(t); m_cat(m, t); } @@ -963,9 +964,10 @@ insert: pool_put(&ipq_pool, fp); m->m_len += (ip->ip_hl << 2); m->m_data -= (ip->ip_hl << 2); - /* some debugging cruft by sklower, below, will go away soon */ - if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ + { int plen = 0; + + KASSERT(m->m_flags & M_PKTHDR); for (t = m; t; t = t->m_next) plen += t->m_len; m->m_pkthdr.len = plen; diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 38631a8159a..5e8721f15e2 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frag6.c,v 1.83 2018/08/22 19:48:48 cheloha Exp $ */ +/* $OpenBSD: frag6.c,v 1.84 2018/09/10 12:47:02 bluhm Exp $ */ /* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */ /* @@ -400,6 +400,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af) t = t->m_next; t->m_next = af6->ip6af_m; m_adj(t->m_next, af6->ip6af_offset); + m_removehdr(t->m_next); pool_put(&ip6af_pool, af6); } @@ -430,8 +431,10 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af) pool_put(&ip6q_pool, q6); - if (m->m_flags & M_PKTHDR) { /* Isn't it always true? */ + { int plen = 0; + + KASSERT(m->m_flags & M_PKTHDR); for (t = m; t; t = t->m_next) plen += t->m_len; m->m_pkthdr.len = plen; diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 8c2f21b690b..8a9df640faf 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mbuf.h,v 1.236 2018/07/10 09:28:27 henning Exp $ */ +/* $OpenBSD: mbuf.h,v 1.237 2018/09/10 12:47:02 bluhm Exp $ */ /* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */ /* @@ -441,6 +441,7 @@ struct mbuf *m_get(int, int); struct mbuf *m_getclr(int, int); struct mbuf *m_gethdr(int, int); struct mbuf *m_inithdr(struct mbuf *); +void m_removehdr(struct mbuf *); void m_resethdr(struct mbuf *); int m_defrag(struct mbuf *, int); struct mbuf *m_prepend(struct mbuf *, int, int); -- 2.20.1