kern/158426: commit references a PR
dfilter service
dfilter at FreeBSD.ORG
Mon Aug 22 23:40:12 UTC 2011
The following reply was made to PR kern/158426; it has been noted by GNATS.
From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:
Subject: Re: kern/158426: commit references a PR
Date: Mon, 22 Aug 2011 23:39:50 +0000 (UTC)
Author: pluknet
Date: Mon Aug 22 23:39:40 2011
New Revision: 225096
URL: http://svn.freebsd.org/changeset/base/225096
Log:
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)
Modified:
head/sys/netinet6/mld6.c
Modified: head/sys/netinet6/mld6.c
==============================================================================
--- head/sys/netinet6/mld6.c Mon Aug 22 23:27:23 2011 (r225095)
+++ head/sys/netinet6/mld6.c Mon Aug 22 23:39:40 2011 (r225096)
@@ -680,7 +680,6 @@ mld_v1_input_query(struct ifnet *ifp, co
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, co
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, co
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, co
* 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, co
/* 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();
_______________________________________________
svn-src-all at freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
More information about the freebsd-net
mailing list