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();
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to