Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Mar 2012 20:15:18 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r233199 - in stable/8/sys: i386/conf netinet6
Message-ID:  <201203192015.q2JKFItl084480@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Mon Mar 19 20:15:18 2012
New Revision: 233199
URL: http://svn.freebsd.org/changeset/base/233199

Log:
  MFC 225096:
  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().

Modified:
  stable/8/sys/netinet6/mld6.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)
  stable/8/sys/i386/conf/XENHVM   (props changed)

Modified: stable/8/sys/netinet6/mld6.c
==============================================================================
--- stable/8/sys/netinet6/mld6.c	Mon Mar 19 19:53:53 2012	(r233198)
+++ stable/8/sys/netinet6/mld6.c	Mon Mar 19 20:15:18 2012	(r233199)
@@ -681,7 +681,6 @@ mld_v1_input_query(struct ifnet *ifp, co
 
 	IN6_MULTI_LOCK();
 	MLD_LOCK();
-	IF_ADDR_LOCK(ifp);
 
 	/*
 	 * Switch to MLDv1 host compatibility mode.
@@ -694,6 +693,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
@@ -889,7 +889,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));
@@ -937,14 +936,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;
 			}
 		}
@@ -962,10 +965,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?201203192015.q2JKFItl084480>