diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 1111111..3333333 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -2365,7 +2365,16 @@ _m_copyback2(struct mbuf *m0, int off, int len, const void *_cp, int how, m->m_len += min(off + len - m->m_len, tlen); } mlen = min(m->m_len - off, len); + /* + * Writing through an mbuf whose external storage is shared + * (m_sharecount() > 1) silently rewrites every other mbuf + * sharing the cluster -- e.g. bridge flood copies made by + * m_copypacket() (if_bridge.c) whose clusters the original + * still owns. Catch misuse on INVARIANTS kernels; callers + * must unshare first (m_unshare()/m_dup()) before rewriting + * packet data in place. + */ + KASSERT((m->m_flags & M_EXT) == 0 || M_WRITABLE(m), + ("%s: copyback into shared cluster", __func__)); bcopy(cp, mtod(m, caddr_t) + off, mlen); off = 0; cp += mlen;