Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Aug 2011 23:39:40 +0000 (UTC)
From:      Sergey Kandaurov <pluknet@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r225096 - head/sys/netinet6
Message-ID:  <201108222339.p7MNdepu073338@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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();
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108222339.p7MNdepu073338>