⬢ DragonFlyBSD Kernel Audit
DF-5795 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 1111111..2222222 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -2551,9 +2551,10 @@ void
 m_move_pkthdr(struct mbuf *to, struct mbuf *from)
 {
 	KASSERT((to->m_flags & M_PKTHDR), ("%s: not packet header", __func__));
 
 	to->m_flags |= from->m_flags & M_COPYFLAGS;
 	to->m_pkthdr = from->m_pkthdr;		/* especially tags */
 	SLIST_INIT(&from->m_pkthdr.tags);	/* purge tags from src */
+	from->m_flags &= ~M_PKTHDR;	/* from no longer has a pkthdr */
 }
@@ -2024,10 +2025,10 @@ m_unshare(struct mbuf *m0, int how)
 		/*
 		 * Allocate new space to hold the copy...
 		 */
 		/* XXX why can M_PKTHDR be set past the first mbuf? */
 		if (mprev == NULL && (m->m_flags & M_PKTHDR)) {
 			/*
 			 * NB: if a packet header is present we must
-			 * allocate the mbuf separately from any cluster
-			 * because M_MOVE_PKTHDR will smash the data
-			 * pointer and drop the M_EXT marker.
+			 * allocate the mbuf separately from any cluster,
+			 * keeping m's cluster attachment intact for the
+			 * m_free(m) below.  (The old comment described
+			 * FreeBSD's M_MOVE_PKTHDR macro, not ours.)
 			 */
 			MGETHDR(n, how, m->m_type);