Module Name:    src
Committed By:   ozaki-r
Date:           Mon Sep 25 01:56:22 UTC 2017

Modified Files:
        src/sys/net: raw_cb.c raw_cb.h raw_usrreq.c rtsock.c
        src/sys/netipsec: keysock.c

Log Message:
Fix race condition on the rawcb list shared by rtsock and keysock

keysock now protects itself by its own mutex, which means that
the rawcb list is protected by two different mutexes (keysock's one
and softnet_lock for rtsock), of course it's useless.

Fix the situation by having a discrete rawcb list for each.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/net/raw_cb.c
cvs rdiff -u -r1.27 -r1.28 src/sys/net/raw_cb.h
cvs rdiff -u -r1.56 -r1.57 src/sys/net/raw_usrreq.c
cvs rdiff -u -r1.227 -r1.228 src/sys/net/rtsock.c
cvs rdiff -u -r1.60 -r1.61 src/sys/netipsec/keysock.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/net/raw_cb.c
diff -u src/sys/net/raw_cb.c:1.23 src/sys/net/raw_cb.c:1.24
--- src/sys/net/raw_cb.c:1.23	Thu Jul 27 09:53:57 2017
+++ src/sys/net/raw_cb.c	Mon Sep 25 01:56:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_cb.c,v 1.23 2017/07/27 09:53:57 ozaki-r Exp $	*/
+/*	$NetBSD: raw_cb.c,v 1.24 2017/09/25 01:56:22 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_cb.c,v 1.23 2017/07/27 09:53:57 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_cb.c,v 1.24 2017/09/25 01:56:22 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,8 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: raw_cb.c,v 1
  *	redo address binding to allow wildcards
  */
 
-struct rawcbhead	rawcb = LIST_HEAD_INITIALIZER(rawcb);
-
 static u_long		raw_sendspace = RAWSNDQ;
 static u_long		raw_recvspace = RAWRCVQ;
 
@@ -66,7 +64,7 @@ static u_long		raw_recvspace = RAWRCVQ;
  * Allocate a nominal amount of buffer space for the socket.
  */
 int
-raw_attach(struct socket *so, int proto)
+raw_attach(struct socket *so, int proto, struct rawcbhead *rawcbhead)
 {
 	struct rawcb *rp;
 	int error;
@@ -87,7 +85,7 @@ raw_attach(struct socket *so, int proto)
 	rp->rcb_socket = so;
 	rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
 	rp->rcb_proto.sp_protocol = proto;
-	LIST_INSERT_HEAD(&rawcb, rp, rcb_list);
+	LIST_INSERT_HEAD(rawcbhead, rp, rcb_list);
 	KASSERT(solocked(so));
 
 	return 0;

Index: src/sys/net/raw_cb.h
diff -u src/sys/net/raw_cb.h:1.27 src/sys/net/raw_cb.h:1.28
--- src/sys/net/raw_cb.h:1.27	Tue Apr 11 13:55:54 2017
+++ src/sys/net/raw_cb.h	Mon Sep 25 01:56:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_cb.h,v 1.27 2017/04/11 13:55:54 roy Exp $	*/
+/*	$NetBSD: raw_cb.h,v 1.28 2017/09/25 01:56:22 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -60,13 +60,11 @@ struct rawcb {
 #define	RAWRCVQ		8192
 
 LIST_HEAD(rawcbhead, rawcb);
-extern	struct	rawcbhead rawcb;		/* head of list */
 
-int	raw_attach(struct socket *, int);
+int	raw_attach(struct socket *, int, struct rawcbhead *);
 void	*raw_ctlinput(int, const struct sockaddr *, void *);
 void	raw_detach(struct socket *);
 void	raw_disconnect(struct rawcb *);
-void	raw_init(void);
 void	raw_input(struct mbuf *, ...);
 int	raw_usrreq(struct socket *,
 	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);

Index: src/sys/net/raw_usrreq.c
diff -u src/sys/net/raw_usrreq.c:1.56 src/sys/net/raw_usrreq.c:1.57
--- src/sys/net/raw_usrreq.c:1.56	Tue Apr 11 13:55:54 2017
+++ src/sys/net/raw_usrreq.c	Mon Sep 25 01:56:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_usrreq.c,v 1.56 2017/04/11 13:55:54 roy Exp $	*/
+/*	$NetBSD: raw_usrreq.c,v 1.57 2017/09/25 01:56:22 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.56 2017/04/11 13:55:54 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.57 2017/09/25 01:56:22 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -54,12 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c
 #include <net/netisr.h>
 #include <net/raw_cb.h>
 
-void
-raw_init(void)
-{
-	LIST_INIT(&rawcb);
-}
-
 static inline int
 equal(const struct sockaddr *a1, const struct sockaddr *a2)
 {
@@ -79,6 +73,7 @@ raw_input(struct mbuf *m0, ...)
 	va_list ap;
 	struct sockproto *proto;
 	struct sockaddr *src, *dst;
+	struct rawcbhead *rawcbhead;
 
 	KASSERT(mutex_owned(softnet_lock));
 
@@ -86,10 +81,11 @@ raw_input(struct mbuf *m0, ...)
 	proto = va_arg(ap, struct sockproto *);
 	src = va_arg(ap, struct sockaddr *);
 	dst = va_arg(ap, struct sockaddr *);
+	rawcbhead = va_arg(ap, struct rawcbhead *);
 	va_end(ap);
 
 	last = NULL;
-	LIST_FOREACH(rp, &rawcb, rcb_list) {
+	LIST_FOREACH(rp, rawcbhead, rcb_list) {
 		if (rp->rcb_proto.sp_family != proto->sp_family)
 			continue;
 		if (rp->rcb_proto.sp_protocol  &&

Index: src/sys/net/rtsock.c
diff -u src/sys/net/rtsock.c:1.227 src/sys/net/rtsock.c:1.228
--- src/sys/net/rtsock.c:1.227	Sat Jul  1 16:59:12 2017
+++ src/sys/net/rtsock.c	Mon Sep 25 01:56:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtsock.c,v 1.227 2017/07/01 16:59:12 christos Exp $	*/
+/*	$NetBSD: rtsock.c,v 1.228 2017/09/25 01:56:22 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.227 2017/07/01 16:59:12 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.228 2017/09/25 01:56:22 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -239,6 +239,13 @@ COMPATNAME(route_filter)(struct mbuf *m,
 	return 0;
 }
 
+static void
+rt_pr_init(void)
+{
+
+	LIST_INIT(&rt_rawcb);
+}
+
 static int
 COMPATNAME(route_attach)(struct socket *so, int proto)
 {
@@ -253,7 +260,7 @@ COMPATNAME(route_attach)(struct socket *
 	so->so_pcb = rp;
 
 	s = splsoftnet();
-	if ((error = raw_attach(so, proto)) == 0) {
+	if ((error = raw_attach(so, proto, &rt_rawcb)) == 0) {
 		rt_adjustcount(rp->rcb_proto.sp_protocol, 1);
 		rp->rcb_laddr = &COMPATNAME(route_info).ri_src;
 		rp->rcb_faddr = &COMPATNAME(route_info).ri_dst;
@@ -1045,7 +1052,7 @@ flush:
 		proto.sp_protocol = family;
 	if (m)
 		raw_input(m, &proto, &COMPATNAME(route_info).ri_src,
-		    &COMPATNAME(route_info).ri_dst);
+		    &COMPATNAME(route_info).ri_dst, &rt_rawcb);
 	if (rp)
 		rp->rcb_proto.sp_family = PF_XROUTE;
     }
@@ -2027,7 +2034,7 @@ COMPATNAME(route_intr)(void *cookie)
 		if (m == NULL)
 			break;
 		proto.sp_protocol = M_GETCTX(m, uintptr_t);
-		raw_input(m, &proto, &ri->ri_src, &ri->ri_dst);
+		raw_input(m, &proto, &ri->ri_src, &ri->ri_dst, &rt_rawcb);
 	}
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
@@ -2116,7 +2123,7 @@ static const struct protosw COMPATNAME(r
 		.pr_ctlinput = raw_ctlinput,
 		.pr_ctloutput = route_ctloutput,
 		.pr_usrreqs = &route_usrreqs,
-		.pr_init = raw_init,
+		.pr_init = rt_pr_init,
 	},
 };
 

Index: src/sys/netipsec/keysock.c
diff -u src/sys/netipsec/keysock.c:1.60 src/sys/netipsec/keysock.c:1.61
--- src/sys/netipsec/keysock.c:1.60	Tue Aug  8 10:41:33 2017
+++ src/sys/netipsec/keysock.c	Mon Sep 25 01:56:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: keysock.c,v 1.60 2017/08/08 10:41:33 ozaki-r Exp $	*/
+/*	$NetBSD: keysock.c,v 1.61 2017/09/25 01:56:22 ozaki-r Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.60 2017/08/08 10:41:33 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.61 2017/09/25 01:56:22 ozaki-r Exp $");
 
 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
 
@@ -84,6 +84,7 @@ static int key_sendup0(struct rawcb *, s
 int key_registered_sb_max = (2048 * MHLEN); /* XXX arbitrary */
 
 static kmutex_t *key_so_mtx;
+static struct rawcbhead key_rawcb;
 
 void
 key_init_so(void)
@@ -92,6 +93,13 @@ key_init_so(void)
 	key_so_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
 }
 
+static void
+key_pr_init(void)
+{
+
+	LIST_INIT(&key_rawcb);
+}
+
 /*
  * key_output()
  */
@@ -352,7 +360,7 @@ _key_sendup_mbuf(struct socket *so, stru
 		PFKEY_STATINC(PFKEY_STAT_IN_MSGTYPE + msg->sadb_msg_type);
 	}
 
-	LIST_FOREACH(rp, &rawcb, rcb_list)
+	LIST_FOREACH(rp, &key_rawcb, rcb_list)
 	{
 		struct socket * kso = rp->rcb_socket;
 		if (rp->rcb_proto.sp_family != PF_KEY)
@@ -469,7 +477,7 @@ key_attach(struct socket *so, int proto)
 	so->so_lock = key_so_mtx;
 	solock(so);
 
-	error = raw_attach(so, proto);
+	error = raw_attach(so, proto, &key_rawcb);
 	if (error) {
 		PFKEY_STATINC(PFKEY_STAT_SOCKERR);
 		kmem_free(kp, sizeof(*kp));
@@ -753,7 +761,7 @@ static const struct protosw keysw[] = {
 	.pr_flags = PR_ATOMIC|PR_ADDR,
 	.pr_ctlinput = raw_ctlinput,
 	.pr_usrreqs = &key_usrreqs,
-	.pr_init = raw_init,
+	.pr_init = key_pr_init,
     }
 };
 

Reply via email to