DF-3451 / fix.diff
--- 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 |