mbuf: avoid assertion failure when splitting mbuf cluster
From OpenBSD: commit 7b4d35e0a60ba1dd4daf4b1c2932020a22463a89 Author: bluhm <bluhm@openbsd.org> Date: Fri Oct 20 16:25:15 2023 +0000 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@ The issue is harmless if DIAGNOSTIC is not enabled. XXX pullup-10 XXX pullup-9
This commit is contained in:
parent
c9712969ab
commit
e629b37024
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: uipc_mbuf.c,v 1.251 2023/04/12 06:48:08 riastradh Exp $ */
|
/* $NetBSD: uipc_mbuf.c,v 1.252 2023/11/27 02:50:27 ozaki-r Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2001, 2018 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999, 2001, 2018 The NetBSD Foundation, Inc.
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.251 2023/04/12 06:48:08 riastradh Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.252 2023/11/27 02:50:27 ozaki-r Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_mbuftrace.h"
|
#include "opt_mbuftrace.h"
|
||||||
|
@ -1343,10 +1343,7 @@ m_split_internal(struct mbuf *m0, int len0, int wait, bool copyhdr)
|
||||||
len_save = m0->m_pkthdr.len;
|
len_save = m0->m_pkthdr.len;
|
||||||
m0->m_pkthdr.len = len0;
|
m0->m_pkthdr.len = len0;
|
||||||
|
|
||||||
if (m->m_flags & M_EXT)
|
if ((m->m_flags & M_EXT) == 0 && remain > MHLEN) {
|
||||||
goto extpacket;
|
|
||||||
|
|
||||||
if (remain > MHLEN) {
|
|
||||||
/* m can't be the lead packet */
|
/* m can't be the lead packet */
|
||||||
m_align(n, 0);
|
m_align(n, 0);
|
||||||
n->m_len = 0;
|
n->m_len = 0;
|
||||||
|
@ -1357,8 +1354,6 @@ m_split_internal(struct mbuf *m0, int len0, int wait, bool copyhdr)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
} else {
|
|
||||||
m_align(n, remain);
|
|
||||||
}
|
}
|
||||||
} else if (remain == 0) {
|
} else if (remain == 0) {
|
||||||
n = m->m_next;
|
n = m->m_next;
|
||||||
|
@ -1369,14 +1364,13 @@ m_split_internal(struct mbuf *m0, int len0, int wait, bool copyhdr)
|
||||||
if (n == NULL)
|
if (n == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
MCLAIM(n, m->m_owner);
|
MCLAIM(n, m->m_owner);
|
||||||
m_align(n, remain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extpacket:
|
|
||||||
if (m->m_flags & M_EXT) {
|
if (m->m_flags & M_EXT) {
|
||||||
n->m_data = m->m_data + len;
|
n->m_data = m->m_data + len;
|
||||||
MCLADDREFERENCE(m, n);
|
MCLADDREFERENCE(m, n);
|
||||||
} else {
|
} else {
|
||||||
|
m_align(n, remain);
|
||||||
memcpy(mtod(n, void *), mtod(m, char *) + len, remain);
|
memcpy(mtod(n, void *), mtod(m, char *) + len, remain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue