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>