⬢ DragonFlyBSD Kernel Audit
DF-3451 / fix.diff
← back to finding ↓ download raw
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -163,6 +163,14 @@
 void
 mld6_stop_listening(struct in6_multi *in6m)
 {
+	/*
+	 * DF-3451: every other MLD path (start_listening, input,
+	 * fasttimeo) serializes on mld6_token; stop_listening wrote
+	 * the shared link-local templates without it, so a concurrent
+	 * mld6_input on another CPU could read a torn if_index
+	 * embedding and address reports/DONEs to the wrong group.
+	 */
+	lwkt_gettoken(&mld6_token);
 	mld6_all_nodes_linklocal.s6_addr16[1] =
 		htons(in6m->in6m_ifp->if_index); /* XXX */
 	mld6_all_routers_linklocal.s6_addr16[1] =
@@ -173,6 +181,7 @@
 	    IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) > IPV6_ADDR_SCOPE_INTFACELOCAL)
 		mld6_sendpkt(in6m, MLD_LISTENER_DONE,
 			     &mld6_all_routers_linklocal);
+	lwkt_reltoken(&mld6_token);
 }
 
 void