Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jul 2026 13:50:37 +0000
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        KUROSAWA Takahiro <takahiro.kurosawa@gmail.com>
Subject:   git: f2202ab5abda - main - mbuf: make m_unshare() allow unmapped mbufs
Message-ID:  <6a57902d.3970d.2efed0b3@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=f2202ab5abda7fb09538a1ceda77569b67d83084

commit f2202ab5abda7fb09538a1ceda77569b67d83084
Author:     KUROSAWA Takahiro <takahiro.kurosawa@gmail.com>
AuthorDate: 2026-07-15 08:28:00 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-07-15 11:44:59 +0000

    mbuf: make m_unshare() allow unmapped mbufs
    
    m_unshare() had crashed if unmapped mbufs exist in the mbuf chain.
    This was because memcpy() with mtod() was used without making sure that
    the mbuf was mapped. Use m_copydata() that cares unmapped mbufs instead.
    
    Reviewed by:    gallatin
    Differential Revision:  https://reviews.freebsd.org/D58189
---
 sys/kern/uipc_mbuf.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index b3632c0bfff6..ffdd115e3e0a 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -2160,7 +2160,8 @@ m_unshare(struct mbuf *m0, int how)
 		 * crypto operations, especially when using hardware.
 		 */
 		if ((m->m_flags & M_EXT) == 0) {
-			if (mprev && (mprev->m_flags & M_EXT) &&
+			if (mprev &&
+			    (mprev->m_flags & (M_EXT | M_EXTPG)) == M_EXT &&
 			    m->m_len <= M_TRAILINGSPACE(mprev)) {
 				/* XXX: this ignores mbuf types */
 				memcpy(mtod(mprev, caddr_t) + mprev->m_len,
@@ -2189,11 +2190,12 @@ m_unshare(struct mbuf *m0, int how)
 		 */
 		KASSERT(m->m_flags & M_EXT, ("m_flags 0x%x", m->m_flags));
 		/* NB: we only coalesce into a cluster or larger */
-		if (mprev != NULL && (mprev->m_flags & M_EXT) &&
+		if (mprev != NULL &&
+		    (mprev->m_flags & (M_EXT | M_EXTPG)) == M_EXT &&
 		    m->m_len <= M_TRAILINGSPACE(mprev)) {
 			/* XXX: this ignores mbuf types */
-			memcpy(mtod(mprev, caddr_t) + mprev->m_len,
-			    mtod(m, caddr_t), m->m_len);
+			m_copydata(m, 0, m->m_len,
+			    mtod(mprev, caddr_t) + mprev->m_len);
 			mprev->m_len += m->m_len;
 			mprev->m_next = m->m_next;	/* unlink from chain */
 			m_free(m);			/* reclaim mbuf */
@@ -2224,7 +2226,7 @@ m_unshare(struct mbuf *m0, int how)
 		mlast = NULL;
 		for (;;) {
 			int cc = min(len, MCLBYTES);
-			memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + off, cc);
+			m_copydata(m, off, cc, mtod(n, caddr_t));
 			n->m_len = cc;
 			if (mlast != NULL)
 				mlast->m_next = n;


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a57902d.3970d.2efed0b3>