From 7b4d35e0a60ba1dd4daf4b1c2932020a22463a89 Mon Sep 17 00:00:00 2001 From: bluhm Date: Fri, 20 Oct 2023 16:25:15 +0000 Subject: [PATCH] Avoid assertion failure when splitting mbuf cluster. m_split() calls m_align() to initialize the data pointer of newly allocated mbuf. If the new mbuf will be converted to a cluster, this is not necessary. If additionally the new mbuf is larger than MLEN, this can lead to a panic. Only call m_align() when a valid m_data is needed. This is the case if we do not refecence the existing cluster, but memcpy() the data into the new mbuf. Reported-by: syzbot+0e6817f5877926f0e96a@syzkaller.appspotmail.com OK claudio@ deraadt@ --- sys/kern/uipc_mbuf.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index ba59f13a954..5d1f9a7b802 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.287 2023/06/23 04:36:49 gnezdo Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.288 2023/10/20 16:25:15 bluhm Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -1080,9 +1080,7 @@ m_split(struct mbuf *m0, int len0, int wait) n->m_len = 0; return (n); } - if (m->m_flags & M_EXT) - goto extpacket; - if (remain > MHLEN) { + if ((m->m_flags & M_EXT) == 0 && remain > MHLEN) { /* m can't be the lead packet */ m_align(n, 0); n->m_next = m_split(m, len, wait); @@ -1094,8 +1092,7 @@ m_split(struct mbuf *m0, int len0, int wait) n->m_len = 0; return (n); } - } else - m_align(n, remain); + } } else if (remain == 0) { n = m->m_next; m->m_next = NULL; @@ -1104,14 +1101,13 @@ m_split(struct mbuf *m0, int len0, int wait) MGET(n, wait, m->m_type); if (n == NULL) return (NULL); - m_align(n, remain); } -extpacket: if (m->m_flags & M_EXT) { n->m_ext = m->m_ext; MCLADDREFERENCE(m, n); n->m_data = m->m_data + len; } else { + m_align(n, remain); memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + len, remain); } n->m_len = remain; -- 2.20.1