Module Name:    src
Committed By:   ozaki-r
Date:           Thu Mar  2 05:29:31 UTC 2017

Modified Files:
        src/sys/netinet: in_pcb.c in_pcb.h ip_output.c

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


To generate a diff of this commit:
cvs rdiff -u -r1.175 -r1.176 src/sys/netinet/in_pcb.c
cvs rdiff -u -r1.62 -r1.63 src/sys/netinet/in_pcb.h
cvs rdiff -u -r1.273 -r1.274 src/sys/netinet/ip_output.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/in_pcb.c
diff -u src/sys/netinet/in_pcb.c:1.175 src/sys/netinet/in_pcb.c:1.176
--- src/sys/netinet/in_pcb.c:1.175	Mon Feb 13 04:05:58 2017
+++ src/sys/netinet/in_pcb.c	Thu Mar  2 05:29:31 2017
@@ -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 @@ in_purgeifmcast(struct ip_moptions *imo,
 {
 	int i, gap;
 
+	/* The owner of imo should be protected by solock */
 	KASSERT(ifp != NULL);
 
 	if (imo == NULL)
@@ -755,9 +756,21 @@ in_pcbpurgeif0(struct inpcbtable *table,
 
 	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);
 	}
 }
 

Index: src/sys/netinet/in_pcb.h
diff -u src/sys/netinet/in_pcb.h:1.62 src/sys/netinet/in_pcb.h:1.63
--- src/sys/netinet/in_pcb.h:1.62	Wed Feb 22 07:05:04 2017
+++ src/sys/netinet/in_pcb.h	Thu Mar  2 05:29:31 2017
@@ -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 @@ struct inpcb {
 				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 *);

Index: src/sys/netinet/ip_output.c
diff -u src/sys/netinet/ip_output.c:1.273 src/sys/netinet/ip_output.c:1.274
--- src/sys/netinet/ip_output.c:1.273	Thu Mar  2 05:24:23 2017
+++ src/sys/netinet/ip_output.c	Thu Mar  2 05:29:31 2017
@@ -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 @@ ip_pcbopts(struct inpcb *inp, const stru
 	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 @@ ip_add_membership(struct ip_moptions *im
 	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 @@ ip_setmoptions(struct ip_moptions **pimo
 	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 @@ ip_freemoptions(struct ip_moptions *imo)
 {
 	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]);

Reply via email to