summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_mbuf.c
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2015-06-30 17:19:58 +0000
committernp <np@FreeBSD.org>2015-06-30 17:19:58 +0000
commita503d4a154104ab423b21d9677afa7923122f4f5 (patch)
tree6f19faa9ca7b7f1a889c4544f7be487af0765fc7 /sys/kern/uipc_mbuf.c
parent8b5b408c2c62fe7ff51161d7e59c3d1798f71834 (diff)
downloadFreeBSD-src-a503d4a154104ab423b21d9677afa7923122f4f5.zip
FreeBSD-src-a503d4a154104ab423b21d9677afa7923122f4f5.tar.gz
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@
Diffstat (limited to 'sys/kern/uipc_mbuf.c')
-rw-r--r--sys/kern/uipc_mbuf.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index b77d476..c0c467c 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -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 flags)
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);
}
}
OpenPOWER on IntegriCloud