Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Jul 2018 06:47:34 +0000 (UTC)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335932 - head/sys/netinet
Message-ID:  <201807040647.w646lYpW098639@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hrs
Date: Wed Jul  4 06:47:34 2018
New Revision: 335932
URL: https://svnweb.freebsd.org/changeset/base/335932

Log:
  - Fix a double unlock in inp_block_unblock_source() and
    lock leakage in inp_leave_group() which caused a panic.
  - Make order of CTR1() and IN_MULTI_LIST_LOCK() consistent
    around inm_merge().

Modified:
  head/sys/netinet/in_mcast.c

Modified: head/sys/netinet/in_mcast.c
==============================================================================
--- head/sys/netinet/in_mcast.c	Wed Jul  4 03:54:39 2018	(r335931)
+++ head/sys/netinet/in_mcast.c	Wed Jul  4 06:47:34 2018	(r335932)
@@ -1579,23 +1579,24 @@ inp_block_unblock_source(struct inpcb *inp, struct soc
 	 * Begin state merge transaction at IGMP layer.
 	 */
 	IN_MULTI_LOCK();
-	IN_MULTI_LIST_LOCK();
 	CTR1(KTR_IGMPV3, "%s: merge inm state", __func__);
+	IN_MULTI_LIST_LOCK();
 	error = inm_merge(inm, imf);
 	if (error) {
 		CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__);
+		IN_MULTI_LIST_UNLOCK();
 		goto out_in_multi_locked;
 	}
 
 	CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
 	error = igmp_change_state(inm);
+	IN_MULTI_LIST_UNLOCK();
 	if (error)
 		CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__);
 
 out_in_multi_locked:
 
 	IN_MULTI_UNLOCK();
-	IN_MULTI_UNLOCK();
 out_imf_rollback:
 	if (error)
 		imf_rollback(imf);
@@ -2492,6 +2493,7 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sop
 		if (error) {
 			CTR1(KTR_IGMPV3, "%s: failed to merge inm state",
 			    __func__);
+			IN_MULTI_LIST_UNLOCK();
 			goto out_in_multi_locked;
 		}
 
@@ -2736,12 +2738,12 @@ inp_set_source_filters(struct inpcb *inp, struct socko
 
 	INP_WLOCK_ASSERT(inp);
 	IN_MULTI_LOCK();
-	IN_MULTI_LIST_LOCK();
 
 	/*
 	 * Begin state merge transaction at IGMP layer.
 	 */
 	CTR1(KTR_IGMPV3, "%s: merge inm state", __func__);
+	IN_MULTI_LIST_LOCK();
 	error = inm_merge(inm, imf);
 	if (error) {
 		CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__);



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