summaryrefslogtreecommitdiff
path: root/sys/kern/uipc_mbuf.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2023-10-20 16:25:16 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2023-10-20 16:25:16 +0000
commit28f2bb92c74374ddb722aaf2585d8a137355a141 (patch)
treea8acd95bfc8ecb33fff70247e6041729e07f9cec /sys/kern/uipc_mbuf.c
parentc0d3944dbf2f206e9262ed4b32a79167c462d338 (diff)
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@
Diffstat (limited to 'sys/kern/uipc_mbuf.c')
-rw-r--r--sys/kern/uipc_mbuf.c12
1 files 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;