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, } };