⬢ DragonFlyBSD Kernel Audit
DF-5796 / fix.diff
← back to finding ↓ download raw
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;