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__);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to