mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-06 13:09:50 +00:00
Fix if_addr_mtx recursion in mld6.
mld_set_version() is called only from mld_v1_input_query() and mld_v2_input_query() both holding the if_addr_mtx lock, and then calling into mld_v2_cancel_link_timers() acquires it the second time, which results in mtx recursion. To avoid that, delay if_addr_mtx acquisition until after mld_set_version() is called; while here, further reduce locking scope to protect only the needed pieces: if_multiaddrs, in6m_lookup_locked(). PR: kern/158426 Reported by: Thomas <tps vr-web.de>, Tom Vijlbrief <tom.vijlbrief xs4all.nl> Tested by: Tom Vijlbrief Reviewed by: bz Approved by: re (kib)
This commit is contained in:
parent
11867070c6
commit
0ad2addc9d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225096
@ -680,7 +680,6 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
|
||||
|
||||
IN6_MULTI_LOCK();
|
||||
MLD_LOCK();
|
||||
IF_ADDR_LOCK(ifp);
|
||||
|
||||
/*
|
||||
* Switch to MLDv1 host compatibility mode.
|
||||
@ -693,6 +692,7 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
|
||||
if (timer == 0)
|
||||
timer = 1;
|
||||
|
||||
IF_ADDR_LOCK(ifp);
|
||||
if (is_general_query) {
|
||||
/*
|
||||
* For each reporting group joined on this
|
||||
@ -888,7 +888,6 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
|
||||
|
||||
IN6_MULTI_LOCK();
|
||||
MLD_LOCK();
|
||||
IF_ADDR_LOCK(ifp);
|
||||
|
||||
mli = MLD_IFINFO(ifp);
|
||||
KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp));
|
||||
@ -936,14 +935,18 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
|
||||
* Queries for groups we are not a member of on this
|
||||
* link are simply ignored.
|
||||
*/
|
||||
IF_ADDR_LOCK(ifp);
|
||||
inm = in6m_lookup_locked(ifp, &mld->mld_addr);
|
||||
if (inm == NULL)
|
||||
if (inm == NULL) {
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
goto out_locked;
|
||||
}
|
||||
if (nsrc > 0) {
|
||||
if (!ratecheck(&inm->in6m_lastgsrtv,
|
||||
&V_mld_gsrdelay)) {
|
||||
CTR1(KTR_MLD, "%s: GS query throttled.",
|
||||
__func__);
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
goto out_locked;
|
||||
}
|
||||
}
|
||||
@ -961,10 +964,10 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
|
||||
|
||||
/* XXX Clear embedded scope ID as userland won't expect it. */
|
||||
in6_clearscope(&mld->mld_addr);
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
}
|
||||
|
||||
out_locked:
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
MLD_UNLOCK();
|
||||
IN6_MULTI_UNLOCK();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user