Author: np
Date: Tue Jun 30 17:19:58 2015
New Revision: 284961
URL: https://svnweb.freebsd.org/changeset/base/284961

Log:
  Fix leak in tcp_lro_rx.  Simply clearing M_PKTHDR isn't enough, any tags
  hanging off the header need to be freed too.
  
  Differential Revision:        https://reviews.freebsd.org/D2708
  Reviewed by:  ae@, hiren@

Modified:
  head/sys/kern/uipc_mbuf.c
  head/sys/netinet/tcp_lro.c
  head/sys/sys/mbuf.h

Modified: head/sys/kern/uipc_mbuf.c
==============================================================================
--- head/sys/kern/uipc_mbuf.c   Tue Jun 30 17:09:41 2015        (r284960)
+++ head/sys/kern/uipc_mbuf.c   Tue Jun 30 17:19:58 2015        (r284961)
@@ -420,6 +420,17 @@ mb_dupcl(struct mbuf *n, struct mbuf *m)
        n->m_flags |= m->m_flags & M_RDONLY;
 }
 
+void
+m_demote_pkthdr(struct mbuf *m)
+{
+
+       M_ASSERTPKTHDR(m);
+
+       m_tag_delete_chain(m, NULL);
+       m->m_flags &= ~M_PKTHDR;
+       bzero(&m->m_pkthdr, sizeof(struct pkthdr));
+}
+
 /*
  * Clean up mbuf (chain) from any tags and packet headers.
  * If "all" is set then the first mbuf in the chain will be
@@ -433,11 +444,8 @@ m_demote(struct mbuf *m0, int all, int f
        for (m = all ? m0 : m0->m_next; m != NULL; m = m->m_next) {
                KASSERT(m->m_nextpkt == NULL, ("%s: m_nextpkt in m %p, m0 %p",
                    __func__, m, m0));
-               if (m->m_flags & M_PKTHDR) {
-                       m_tag_delete_chain(m, NULL);
-                       m->m_flags &= ~M_PKTHDR;
-                       bzero(&m->m_pkthdr, sizeof(struct pkthdr));
-               }
+               if (m->m_flags & M_PKTHDR)
+                       m_demote_pkthdr(m);
                m->m_flags = m->m_flags & (M_EXT | M_RDONLY | M_NOFREE | flags);
        }
 }

Modified: head/sys/netinet/tcp_lro.c
==============================================================================
--- head/sys/netinet/tcp_lro.c  Tue Jun 30 17:09:41 2015        (r284960)
+++ head/sys/netinet/tcp_lro.c  Tue Jun 30 17:19:58 2015        (r284961)
@@ -550,7 +550,7 @@ tcp_lro_rx(struct lro_ctrl *lc, struct m
                 * append new segment to existing mbuf chain.
                 */
                m_adj(m, m->m_pkthdr.len - tcp_data_len);
-               m->m_flags &= ~M_PKTHDR;
+               m_demote_pkthdr(m);
 
                le->m_tail->m_next = m;
                le->m_tail = m_last(m);

Modified: head/sys/sys/mbuf.h
==============================================================================
--- head/sys/sys/mbuf.h Tue Jun 30 17:09:41 2015        (r284960)
+++ head/sys/sys/mbuf.h Tue Jun 30 17:19:58 2015        (r284961)
@@ -959,6 +959,7 @@ struct mbuf *m_copypacket(struct mbuf *,
 void            m_copy_pkthdr(struct mbuf *, struct mbuf *);
 struct mbuf    *m_copyup(struct mbuf *, int, int);
 struct mbuf    *m_defrag(struct mbuf *, int);
+void            m_demote_pkthdr(struct mbuf *);
 void            m_demote(struct mbuf *, int, int);
 struct mbuf    *m_devget(char *, int, int, struct ifnet *,
                    void (*)(char *, caddr_t, u_int));
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to