Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet Make sure imo_membership is protected by inp's l...



details:   https://anonhg.NetBSD.org/src/rev/5ba73b07064f
branches:  trunk
changeset: 822119:5ba73b07064f
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Thu Mar 02 05:29:31 2017 +0000

description:
Make sure imo_membership is protected by inp's lock (solock)

diffstat:

 sys/netinet/in_pcb.c    |  17 +++++++++++++++--
 sys/netinet/in_pcb.h    |   6 ++++--
 sys/netinet/ip_output.c |  12 +++++++++---
 3 files changed, 28 insertions(+), 7 deletions(-)

diffs (122 lines):

diff -r 1c0a9a01733b -r 5ba73b07064f sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c      Thu Mar 02 05:27:39 2017 +0000
+++ b/sys/netinet/in_pcb.c      Thu Mar 02 05:29:31 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_pcb.c,v 1.175 2017/02/13 04:05:58 ozaki-r Exp $     */
+/*     $NetBSD: in_pcb.c,v 1.176 2017/03/02 05:29:31 ozaki-r Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -93,7 +93,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.175 2017/02/13 04:05:58 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.176 2017/03/02 05:29:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -722,6 +722,7 @@
 {
        int i, gap;
 
+       /* The owner of imo should be protected by solock */
        KASSERT(ifp != NULL);
 
        if (imo == NULL)
@@ -755,9 +756,21 @@
 
        TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) {
                struct inpcb *inp = (struct inpcb *)inph;
+               bool need_unlock = false;
+
                if (inp->inp_af != AF_INET)
                        continue;
+
+               /* The caller holds either one of inps' lock */
+               if (!inp_locked(inp)) {
+                       inp_lock(inp);
+                       need_unlock = true;
+               }
+
                in_purgeifmcast(inp->inp_moptions, ifp);
+
+               if (need_unlock)
+                       inp_unlock(inp);
        }
 }
 
diff -r 1c0a9a01733b -r 5ba73b07064f sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h      Thu Mar 02 05:27:39 2017 +0000
+++ b/sys/netinet/in_pcb.h      Thu Mar 02 05:29:31 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_pcb.h,v 1.62 2017/02/22 07:05:04 ozaki-r Exp $      */
+/*     $NetBSD: in_pcb.h,v 1.63 2017/03/02 05:29:31 ozaki-r Exp $      */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -128,7 +128,9 @@
                                INP_PKTINFO)
 
 #define        sotoinpcb(so)           ((struct inpcb *)(so)->so_pcb)
-#define        inplocked(inp)          solocked((inp)->inp_socket)
+#define        inp_lock(inp)           solock((inp)->inp_socket)
+#define        inp_unlock(inp)         sounlock((inp)->inp_socket)
+#define        inp_locked(inp)         solocked((inp)->inp_socket)
 
 #ifdef _KERNEL
 void   in_losing(struct inpcb *);
diff -r 1c0a9a01733b -r 5ba73b07064f sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c   Thu Mar 02 05:27:39 2017 +0000
+++ b/sys/netinet/ip_output.c   Thu Mar 02 05:29:31 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_output.c,v 1.273 2017/03/02 05:24:23 ozaki-r Exp $  */
+/*     $NetBSD: ip_output.c,v 1.274 2017/03/02 05:29:31 ozaki-r Exp $  */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.273 2017/03/02 05:24:23 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.274 2017/03/02 05:29:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -1337,7 +1337,7 @@
        u_char *dp;
        int cnt;
 
-       KASSERT(inplocked(inp));
+       KASSERT(inp_locked(inp));
 
        /* Turn off any old options. */
        if (inp->inp_options) {
@@ -1587,6 +1587,8 @@
        int i, error, bound;
        struct psref psref;
 
+       /* imo is protected by solock or referenced only by the caller */
+
        bound = curlwp_bind();
        if (sopt->sopt_size == sizeof(struct ip_mreq))
                error = ip_get_membership(sopt, &ifp, &psref, &ia, true);
@@ -1718,6 +1720,8 @@
        struct ifnet *ifp;
        int ifindex, error = 0;
 
+       /* The passed imo isn't NULL, it should be protected by solock */
+
        if (!imo) {
                /*
                 * No multicast option buffer attached to the pcb;
@@ -1880,6 +1884,8 @@
 {
        int i;
 
+       /* The owner of imo (inp) should be protected by solock */
+
        if (imo != NULL) {
                for (i = 0; i < imo->imo_num_memberships; ++i)
                        in_delmulti(imo->imo_membership[i]);



Home | Main Index | Thread Index | Old Index