Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern in m_defrag() must copy data elsewhere before addin...



details:   https://anonhg.NetBSD.org/src/rev/ad76dd311cca
branches:  trunk
changeset: 1009509:ad76dd311cca
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Sat Apr 25 11:03:04 2020 +0000

description:
in m_defrag() must copy data elsewhere before adding cluster, the
data part of mbuf gets reused and hence overwritten by extbuf

diffstat:

 sys/kern/uipc_mbuf.c |  42 +++++++++++++++++++++---------------------
 1 files changed, 21 insertions(+), 21 deletions(-)

diffs (75 lines):

diff -r ac252453d7a4 -r ad76dd311cca sys/kern/uipc_mbuf.c
--- a/sys/kern/uipc_mbuf.c      Sat Apr 25 10:56:53 2020 +0000
+++ b/sys/kern/uipc_mbuf.c      Sat Apr 25 11:03:04 2020 +0000
@@ -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 @@
                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 @@
                                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);



Home | Main Index | Thread Index | Old Index