Lock down rawcb_list, a global list of control blocks for raw sockets,
using rawcb_mtx. Hold this mutex while modifying or iterating over the control list; this means that the mutex is held over calls into socket delivery code, which no longer causes a lock order reversal as the routing socket code uses a netisr to avoid recursing socket -> routing -> socket. Note: Locking of IPsec consumers of rawcb_list is not included in this commit.
This commit is contained in:
parent
7721f5d760
commit
730262cdf7
@ -51,6 +51,7 @@
|
|||||||
* redo address binding to allow wildcards
|
* redo address binding to allow wildcards
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct mtx rawcb_mtx;
|
||||||
struct rawcb_list_head rawcb_list;
|
struct rawcb_list_head rawcb_list;
|
||||||
|
|
||||||
const static u_long raw_sendspace = RAWSNDQ;
|
const static u_long raw_sendspace = RAWSNDQ;
|
||||||
@ -81,7 +82,9 @@ raw_attach(so, proto)
|
|||||||
rp->rcb_socket = so;
|
rp->rcb_socket = so;
|
||||||
rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
|
rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
|
||||||
rp->rcb_proto.sp_protocol = proto;
|
rp->rcb_proto.sp_protocol = proto;
|
||||||
|
mtx_lock(&rawcb_mtx);
|
||||||
LIST_INSERT_HEAD(&rawcb_list, rp, list);
|
LIST_INSERT_HEAD(&rawcb_list, rp, list);
|
||||||
|
mtx_unlock(&rawcb_mtx);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ struct rawcb {
|
|||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
extern LIST_HEAD(rawcb_list_head, rawcb) rawcb_list;
|
extern LIST_HEAD(rawcb_list_head, rawcb) rawcb_list;
|
||||||
|
extern struct mtx rawcb_mtx;
|
||||||
|
|
||||||
/* protosw entries */
|
/* protosw entries */
|
||||||
pr_ctlinput_t raw_ctlinput;
|
pr_ctlinput_t raw_ctlinput;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/mbuf.h>
|
#include <sys/mbuf.h>
|
||||||
@ -44,12 +45,15 @@
|
|||||||
|
|
||||||
#include <net/raw_cb.h>
|
#include <net/raw_cb.h>
|
||||||
|
|
||||||
|
MTX_SYSINIT(rawcb_mtx, &rawcb_mtx, "rawcb", MTX_DEF);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize raw connection block q.
|
* Initialize raw connection block q.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
raw_init()
|
raw_init()
|
||||||
{
|
{
|
||||||
|
|
||||||
LIST_INIT(&rawcb_list);
|
LIST_INIT(&rawcb_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +77,7 @@ raw_input(m0, proto, src, dst)
|
|||||||
struct socket *last;
|
struct socket *last;
|
||||||
|
|
||||||
last = 0;
|
last = 0;
|
||||||
|
mtx_lock(&rawcb_mtx);
|
||||||
LIST_FOREACH(rp, &rawcb_list, list) {
|
LIST_FOREACH(rp, &rawcb_list, list) {
|
||||||
if (rp->rcb_proto.sp_family != proto->sp_family)
|
if (rp->rcb_proto.sp_family != proto->sp_family)
|
||||||
continue;
|
continue;
|
||||||
@ -117,6 +122,7 @@ raw_input(m0, proto, src, dst)
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
|
mtx_unlock(&rawcb_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user