During fragment reassembly, mbuf chains with packet headers were
authorbluhm <bluhm@openbsd.org>
Mon, 10 Sep 2018 12:47:02 +0000 (12:47 +0000)
committerbluhm <bluhm@openbsd.org>
Mon, 10 Sep 2018 12:47:02 +0000 (12:47 +0000)
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
sys/kern/uipc_mbuf.c
sys/net/pf_norm.c
sys/netinet/ip_input.c
sys/netinet6/frag6.c
sys/sys/mbuf.h

index d70a070..d08f1d2 100644 (file)
@@ -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 <jjbg@openbsd.org>
 .\" 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.
index 5bb5c62..2dda4b5 100644 (file)
@@ -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;
index a328c9b..d60dd43 100644 (file)
@@ -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 <provos@citi.umich.edu>
@@ -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;
index 4585b7f..3e9bab3 100644 (file)
@@ -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;
index 38631a8..5e8721f 100644 (file)
@@ -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;
index 8c2f21b..8a9df64 100644 (file)
@@ -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);