Module Name: src
Committed By: jdolecek
Date: Sat Apr 25 11:03:04 UTC 2020
Modified Files:
src/sys/kern: uipc_mbuf.c
Log Message:
in m_defrag() must copy data elsewhere before adding cluster, the
data part of mbuf gets reused and hence overwritten by extbuf
To generate a diff of this commit:
cvs rdiff -u -r1.239 -r1.240 src/sys/kern/uipc_mbuf.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/uipc_mbuf.c
diff -u src/sys/kern/uipc_mbuf.c:1.239 src/sys/kern/uipc_mbuf.c:1.240
--- src/sys/kern/uipc_mbuf.c:1.239 Fri Apr 24 22:50:55 2020
+++ src/sys/kern/uipc_mbuf.c Sat Apr 25 11:03:04 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_mbuf.c,v 1.239 2020/04/24 22:50:55 jdolecek Exp $ */
+/* $NetBSD: uipc_mbuf.c,v 1.240 2020/04/25 11:03:04 jdolecek Exp $ */
/*
* Copyright (c) 1999, 2001, 2018 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.239 2020/04/24 22:50:55 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.240 2020/04/25 11:03:04 jdolecek Exp $");
#ifdef _KERNEL_OPT
#include "opt_mbuftrace.h"
@@ -1677,7 +1677,7 @@ m_defrag(struct mbuf *m, int how)
return m;
/* Defrag to single mbuf if at all possible */
- if ((m->m_flags & M_EXT) == 0) {
+ if ((m->m_flags & M_EXT) == 0 && m->m_pkthdr.len <= MCLBYTES) {
if (m->m_pkthdr.len <= MHLEN) {
if (M_TRAILINGSPACE(m) < (m->m_pkthdr.len - m->m_len)) {
KASSERT(M_LEADINGSPACE(m) >=
@@ -1685,29 +1685,29 @@ m_defrag(struct mbuf *m, int how)
memmove(m->m_pktdat, m->m_data, m->m_len);
m->m_data = m->m_pktdat;
}
-
- KASSERT(M_TRAILINGSPACE(m) >=
- (m->m_pkthdr.len - m->m_len));
- if (__predict_false(!m_ensure_contig(&m,
- m->m_pkthdr.len))) {
- panic("m_ensure_contig(%d) failed\n",
- m->m_pkthdr.len);
- }
- return m;
- } else if (m->m_pkthdr.len <= MCLBYTES) {
- void *odata = m->m_data;
+ } else {
+ /* Must copy data before adding cluster */
+ m0 = m_get(how, MT_DATA);
+ if (m0 == NULL)
+ return NULL;
+ KASSERT(m->m_len <= MHLEN);
+ m_copydata(m, 0, m->m_len, mtod(m0, void *));
MCLGET(m, how);
- if ((m->m_flags & M_EXT) == 0)
+ if ((m->m_flags & M_EXT) == 0) {
+ m_free(m0);
return NULL;
- memcpy(m->m_data, odata, m->m_len);
- if (m_pulldown(m, m->m_len, m->m_pkthdr.len - m->m_len,
- NULL) == NULL) {
- panic("m_pulldown(%d, %d) failed\n",
- m->m_len, m->m_pkthdr.len - m->m_len);
}
- return m;
+ memcpy(m->m_data, mtod(m0, void *), m->m_len);
+ m_free(m0);
}
+ KASSERT(M_TRAILINGSPACE(m) >= (m->m_pkthdr.len - m->m_len));
+ m_copydata(m->m_next, 0, m->m_pkthdr.len - m->m_len,
+ mtod(m, char *) + m->m_len);
+ m->m_len = m->m_pkthdr.len;
+ m_freem(m->m_next);
+ m->m_next = NULL;
+ return m;
}
m0 = m_get(how, MT_DATA);