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.
This commit is contained in:
parent
1a3d098173
commit
475ed81624
|
@ -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.23 2017/07/27 09:53:57 ozaki-r Exp $");
|
|||
* 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;
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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,v 1.56 2017/04/11 13:55:54 roy Exp $");
|
|||
#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 &&
|
||||
|
|
|
@ -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, struct sockproto *proto,
|
|||
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, int proto)
|
|||
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(route_protosw)[] = {
|
|||
.pr_ctlinput = raw_ctlinput,
|
||||
.pr_ctloutput = route_ctloutput,
|
||||
.pr_usrreqs = &route_usrreqs,
|
||||
.pr_init = raw_init,
|
||||
.pr_init = rt_pr_init,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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 *, struct mbuf *, int, int);
|
|||
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, struct mbuf *m,
|
|||
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,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue