svn commit: r284961 - in head/sys: kern netinet sys

Navdeep Parhar np at FreeBSD.org
Tue Jun 30 17:20:00 UTC 2015


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));


More information about the svn-src-all mailing list