From owner-svn-src-all@freebsd.org Tue Jun 30 17:20:00 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3B90D990AD7; Tue, 30 Jun 2015 17:20:00 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1304018E4; Tue, 30 Jun 2015 17:20:00 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t5UHJxXq011527; Tue, 30 Jun 2015 17:19:59 GMT (envelope-from np@FreeBSD.org) Received: (from np@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t5UHJxlE011522; Tue, 30 Jun 2015 17:19:59 GMT (envelope-from np@FreeBSD.org) Message-Id: <201506301719.t5UHJxlE011522@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: np set sender to np@FreeBSD.org using -f From: Navdeep Parhar Date: Tue, 30 Jun 2015 17:19:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r284961 - in head/sys: kern netinet sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Jun 2015 17:20:00 -0000 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));