summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2018-10-04 17:33:40 +0000
committerbluhm <bluhm@openbsd.org>2018-10-04 17:33:40 +0000
commit3022661327119d66e40f035bd4a885e7569f1e0e (patch)
tree172d93471cc2c54a1434d0ab548fc8d5e68022f3
parentPlug TLS context leak in nc(1) server and client mode. Move (diff)
downloadwireguard-openbsd-3022661327119d66e40f035bd4a885e7569f1e0e.tar.xz
wireguard-openbsd-3022661327119d66e40f035bd4a885e7569f1e0e.zip
Revert the inpcb table mutex commit. It triggers a witness panic
in raw IP delivery and UDP broadcast loops. There inpcbtable_mtx is held and sorwakeup() is called within the loop. As sowakeup() grabs the kernel lock, we have a lock ordering problem. found by Hrvoje Popovski; OK deraadt@ mpi@
-rw-r--r--sys/kern/kern_sysctl.c37
-rw-r--r--sys/netinet/in_pcb.c53
-rw-r--r--sys/netinet/in_pcb.h35
-rw-r--r--sys/netinet/ip_divert.c4
-rw-r--r--sys/netinet/raw_ip.c5
-rw-r--r--sys/netinet/tcp_subr.c4
-rw-r--r--sys/netinet/udp_usrreq.c4
-rw-r--r--sys/netinet6/in6_pcb.c17
-rw-r--r--sys/netinet6/ip6_divert.c4
-rw-r--r--sys/netinet6/raw_ip6.c9
10 files changed, 36 insertions, 136 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 8b0da7c6475..a36b3b3864a 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.348 2018/09/26 17:23:13 cheloha Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.349 2018/10/04 17:33:40 bluhm Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -1179,8 +1179,7 @@ fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp,
kf->inp_rtableid = inpcb->inp_rtableid;
if (so->so_type == SOCK_RAW)
kf->inp_proto = inpcb->inp_ip.ip_p;
- if (so->so_proto->pr_protocol == IPPROTO_TCP &&
- inpcb->inp_ppcb != NULL) {
+ if (so->so_proto->pr_protocol == IPPROTO_TCP) {
struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
kf->t_rcv_wnd = tcpcb->rcv_wnd;
kf->t_snd_wnd = tcpcb->snd_wnd;
@@ -1207,8 +1206,7 @@ fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp,
kf->inp_rtableid = inpcb->inp_rtableid;
if (so->so_type == SOCK_RAW)
kf->inp_proto = inpcb->inp_ipv6.ip6_nxt;
- if (so->so_proto->pr_protocol == IPPROTO_TCP &&
- inpcb->inp_ppcb != NULL) {
+ if (so->so_proto->pr_protocol == IPPROTO_TCP) {
struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
kf->t_rcv_wnd = tcpcb->rcv_wnd;
kf->t_snd_wnd = tcpcb->snd_wnd;
@@ -1322,16 +1320,10 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
} \
needed += elem_size; \
} while (0)
-
#define FILLIT(fp, fdp, i, vp, pr) \
FILLIT2(fp, fdp, i, vp, pr, NULL)
-
-#define FILLINPCB(inp) do { \
- mtx_enter(&inp->inp_mtx); \
- if (inp->inp_socket != NULL) \
- FILLIT2(NULL, NULL, 0, NULL, NULL, inp->inp_socket); \
- mtx_leave(&inp->inp_mtx); \
-} while (0)
+#define FILLSO(so) \
+ FILLIT2(NULL, NULL, 0, NULL, NULL, so)
switch (op) {
case KERN_FILE_BYFILE:
@@ -1339,26 +1331,19 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
if (arg == DTYPE_SOCKET) {
struct inpcb *inp;
- /*
- * The inpcb and socket fields are accessed and read
- * without net lock. This may result in inconsistent
- * data provided to userland. The fix will be to
- * protect the socket fields with the inpcb mutex.
- * XXXSMP
- */
- mtx_enter(&inpcbtable_mtx);
+ NET_LOCK();
TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue)
- FILLINPCB(inp);
+ FILLSO(inp->inp_socket);
TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue)
- FILLINPCB(inp);
+ FILLSO(inp->inp_socket);
TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue)
- FILLINPCB(inp);
+ FILLSO(inp->inp_socket);
#ifdef INET6
TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue,
inp_queue)
- FILLINPCB(inp);
+ FILLSO(inp->inp_socket);
#endif
- mtx_leave(&inpcbtable_mtx);
+ NET_UNLOCK();
}
fp = NULL;
while ((fp = fd_iterfile(fp, p)) != NULL) {
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 1d5fd6ff4ee..e1b876919d2 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.246 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.247 2018/10/04 17:33:41 bluhm Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -111,16 +111,12 @@ int ipport_lastauto = IPPORT_USERRESERVED;
int ipport_hifirstauto = IPPORT_HIFIRSTAUTO;
int ipport_hilastauto = IPPORT_HILASTAUTO;
-/* Protect PCB table queues, lookup hashes and existence of inpcb. */
-struct mutex inpcbtable_mtx = MUTEX_INITIALIZER(IPL_SOFTNET);
-
struct baddynamicports baddynamicports;
struct baddynamicports rootonlyports;
struct pool inpcb_pool;
int inpcb_pool_initialized = 0;
-void in_pcbrehash_locked(struct inpcb *);
-int in_pcbresize(struct inpcbtable *, int);
+int in_pcbresize (struct inpcbtable *, int);
#define INPCBHASH_LOADFACTOR(_x) (((_x) * 3) / 4)
@@ -163,7 +159,6 @@ void
in_pcbinit(struct inpcbtable *table, int hashsize)
{
- mtx_enter(&inpcbtable_mtx);
TAILQ_INIT(&table->inpt_queue);
table->inpt_hashtbl = hashinit(hashsize, M_PCB, M_NOWAIT,
&table->inpt_mask);
@@ -177,7 +172,6 @@ in_pcbinit(struct inpcbtable *table, int hashsize)
table->inpt_size = hashsize;
arc4random_buf(&table->inpt_key, sizeof(table->inpt_key));
arc4random_buf(&table->inpt_lkey, sizeof(table->inpt_lkey));
- mtx_leave(&inpcbtable_mtx);
}
/*
@@ -252,7 +246,6 @@ in_pcballoc(struct socket *so, struct inpcbtable *table)
inp->inp_cksum6 = -1;
#endif /* INET6 */
- mtx_enter(&inpcbtable_mtx);
if (table->inpt_count++ > INPCBHASH_LOADFACTOR(table->inpt_size))
(void)in_pcbresize(table, table->inpt_size * 2);
TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue);
@@ -269,8 +262,6 @@ in_pcballoc(struct socket *so, struct inpcbtable *table)
&inp->inp_faddr, inp->inp_fport,
&inp->inp_laddr, inp->inp_lport);
LIST_INSERT_HEAD(head, inp, inp_hash);
- mtx_leave(&inpcbtable_mtx);
-
so->so_pcb = inp;
return (0);
@@ -554,15 +545,10 @@ in_pcbdisconnect(struct inpcb *inp)
void
in_pcbdetach(struct inpcb *inp)
{
- struct socket *so;
+ struct socket *so = inp->inp_socket;
NET_ASSERT_LOCKED();
- mtx_enter(&inp->inp_mtx);
- so = inp->inp_socket;
- inp->inp_socket = NULL;
- mtx_leave(&inp->inp_mtx);
-
so->so_pcb = NULL;
/*
* As long as the NET_LOCK() is the default lock for Internet
@@ -589,12 +575,10 @@ in_pcbdetach(struct inpcb *inp)
pf_inp_unlink(inp);
}
#endif
- mtx_enter(&inpcbtable_mtx);
LIST_REMOVE(inp, inp_lhash);
LIST_REMOVE(inp, inp_hash);
TAILQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue);
inp->inp_table->inpt_count--;
- mtx_leave(&inpcbtable_mtx);
in_pcbunref(inp);
}
@@ -610,7 +594,6 @@ void
in_pcbunref(struct inpcb *inp)
{
if (refcnt_rele(&inp->inp_refcnt)) {
- KASSERT(inp->inp_socket == NULL);
KASSERT((LIST_NEXT(inp, inp_hash) == NULL) ||
(LIST_NEXT(inp, inp_hash) == _Q_INVALID));
KASSERT((LIST_NEXT(inp, inp_lhash) == NULL) ||
@@ -689,8 +672,6 @@ in_pcbnotifyall(struct inpcbtable *table, struct sockaddr *dst, u_int rtable,
return;
rdomain = rtable_l2(rtable);
- KERNEL_LOCK();
- mtx_enter(&inpcbtable_mtx);
TAILQ_FOREACH_SAFE(inp, &table->inpt_queue, inp_queue, ninp) {
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
@@ -701,17 +682,9 @@ in_pcbnotifyall(struct inpcbtable *table, struct sockaddr *dst, u_int rtable,
inp->inp_socket == NULL) {
continue;
}
- /*
- * The notify functions may grab the kernel lock. Sometimes
- * we already hold the kernel lock when we acquire the pcb
- * mutex. So do an extra kernel lock before the mutex outside
- * of this loop. XXXSMP
- */
if (notify)
(*notify)(inp, errno);
}
- mtx_leave(&inpcbtable_mtx);
- KERNEL_UNLOCK();
}
/*
@@ -784,7 +757,6 @@ in_pcblookup_local(struct inpcbtable *table, void *laddrp, u_int lport_arg,
u_int rdomain;
rdomain = rtable_l2(rtable);
- mtx_enter(&inpcbtable_mtx);
head = in_pcblhash(table, rdomain, lport);
LIST_FOREACH(inp, head, inp_lhash) {
if (rtable_l2(inp->inp_rtableid) != rdomain)
@@ -835,8 +807,6 @@ in_pcblookup_local(struct inpcbtable *table, void *laddrp, u_int lport_arg,
break;
}
}
- mtx_leave(&inpcbtable_mtx);
-
return (match);
}
@@ -982,19 +952,10 @@ in_pcbselsrc(struct in_addr **insrc, struct sockaddr_in *sin,
void
in_pcbrehash(struct inpcb *inp)
{
- mtx_enter(&inpcbtable_mtx);
- in_pcbrehash_locked(inp);
- mtx_leave(&inpcbtable_mtx);
-}
-
-void
-in_pcbrehash_locked(struct inpcb *inp)
-{
struct inpcbtable *table = inp->inp_table;
struct inpcbhead *head;
NET_ASSERT_LOCKED();
- MUTEX_ASSERT_LOCKED(&inpcbtable_mtx);
LIST_REMOVE(inp, inp_lhash);
head = in_pcblhash(table, inp->inp_rtableid, inp->inp_lport);
@@ -1021,8 +982,6 @@ in_pcbresize(struct inpcbtable *table, int hashsize)
void *nhashtbl, *nlhashtbl, *ohashtbl, *olhashtbl;
struct inpcb *inp;
- MUTEX_ASSERT_LOCKED(&inpcbtable_mtx);
-
ohashtbl = table->inpt_hashtbl;
olhashtbl = table->inpt_lhashtbl;
osize = table->inpt_size;
@@ -1044,7 +1003,7 @@ in_pcbresize(struct inpcbtable *table, int hashsize)
arc4random_buf(&table->inpt_lkey, sizeof(table->inpt_lkey));
TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) {
- in_pcbrehash_locked(inp);
+ in_pcbrehash(inp);
}
hashfree(ohashtbl, osize, M_PCB);
hashfree(olhashtbl, osize, M_PCB);
@@ -1075,7 +1034,6 @@ in_pcbhashlookup(struct inpcbtable *table, struct in_addr faddr,
u_int rdomain;
rdomain = rtable_l2(rtable);
- mtx_enter(&inpcbtable_mtx);
head = in_pcbhash(table, rdomain, &faddr, fport, &laddr, lport);
LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
@@ -1098,7 +1056,6 @@ in_pcbhashlookup(struct inpcbtable *table, struct in_addr faddr,
break;
}
}
- mtx_leave(&inpcbtable_mtx);
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: faddr=%08x fport=%d laddr=%08x lport=%d rdom=%u\n",
@@ -1160,7 +1117,6 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
#endif
rdomain = rtable_l2(rtable);
- mtx_enter(&inpcbtable_mtx);
head = in_pcbhash(table, rdomain, &zeroin_addr, 0, key1, lport);
LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
@@ -1197,7 +1153,6 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
LIST_REMOVE(inp, inp_hash);
LIST_INSERT_HEAD(head, inp, inp_hash);
}
- mtx_leave(&inpcbtable_mtx);
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: laddr=%08x lport=%d rdom=%u\n",
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 4ec18dea8ac..a8fa2235c95 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.h,v 1.114 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.115 2018/10/04 17:33:41 bluhm Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@@ -64,7 +64,6 @@
#ifndef _NETINET_IN_PCB_H_
#define _NETINET_IN_PCB_H_
-#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/refcnt.h>
#include <netinet/ip6.h>
@@ -85,12 +84,6 @@ union inpaddru {
};
/*
- * Locks used to protect struct members in this file:
- * I immutable after creation
- * t protected by internet table mutex inpcbtable_mtx
- * p protected by internet PCB mutex inp_mtx
- */
-/*
* Common structure pcb for internet protocol implementation.
* Here are stored pointers to local and foreign host table
* entries, local and foreign socket numbers, and pointers
@@ -98,11 +91,10 @@ union inpaddru {
* control block.
*/
struct inpcb {
- LIST_ENTRY(inpcb) inp_hash; /* [t] local and foreign hash */
- LIST_ENTRY(inpcb) inp_lhash; /* [t] local port hash */
- TAILQ_ENTRY(inpcb) inp_queue; /* [t] inet PCB queue */
- struct inpcbtable *inp_table; /* [I] inet queue/hash table */
- struct mutex inp_mtx; /* protect PCB and socket */
+ LIST_ENTRY(inpcb) inp_hash; /* local and foreign hash */
+ LIST_ENTRY(inpcb) inp_lhash; /* local port hash */
+ TAILQ_ENTRY(inpcb) inp_queue; /* inet PCB queue */
+ struct inpcbtable *inp_table; /* inet queue/hash table */
union inpaddru inp_faddru; /* Foreign address. */
union inpaddru inp_laddru; /* Local address. */
#define inp_faddr inp_faddru.iau_a4u.inaddr
@@ -111,8 +103,8 @@ struct inpcb {
#define inp_laddr6 inp_laddru.iau_addr6
u_int16_t inp_fport; /* foreign port */
u_int16_t inp_lport; /* local port */
- struct socket *inp_socket; /* [p] back pointer to socket */
- caddr_t inp_ppcb; /* [p] pointer to per-protocol pcb */
+ struct socket *inp_socket; /* back pointer to socket */
+ caddr_t inp_ppcb; /* pointer to per-protocol pcb */
union { /* Route (notice increased size). */
struct route ru_route;
struct route_in6 ru_route6;
@@ -158,12 +150,12 @@ struct inpcb {
LIST_HEAD(inpcbhead, inpcb);
struct inpcbtable {
- TAILQ_HEAD(inpthead, inpcb) inpt_queue; /* [t] inet PCB queue */
- struct inpcbhead *inpt_hashtbl; /* [t] local and foreign hash */
- struct inpcbhead *inpt_lhashtbl; /* [t] local port hash */
- SIPHASH_KEY inpt_key, inpt_lkey; /* [t] secrets for hashes */
- u_long inpt_mask, inpt_lmask; /* [t] hash masks */
- int inpt_count, inpt_size; /* [t] queue count, hash size */
+ TAILQ_HEAD(inpthead, inpcb) inpt_queue; /* inet PCB queue */
+ struct inpcbhead *inpt_hashtbl; /* local and foreign hash */
+ struct inpcbhead *inpt_lhashtbl; /* local port hash */
+ SIPHASH_KEY inpt_key, inpt_lkey; /* secrets for hashes */
+ u_long inpt_mask, inpt_lmask; /* hash masks */
+ int inpt_count, inpt_size; /* queue count, hash size */
};
/* flags in inp_flags: */
@@ -257,7 +249,6 @@ struct baddynamicports {
#ifdef _KERNEL
-extern struct mutex inpcbtable_mtx;
extern struct inpcbtable rawcbtable, rawin6pcbtable;
extern struct baddynamicports baddynamicports;
extern struct baddynamicports rootonlyports;
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 48a49ee6d0e..ec6b0dea5b0 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.58 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.59 2018/10/04 17:33:41 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -186,12 +186,10 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port)
return (0);
}
- mtx_enter(&inpcbtable_mtx);
TAILQ_FOREACH(inp, &divbtable.inpt_queue, inp_queue) {
if (inp->inp_lport == divert_port)
break;
}
- mtx_leave(&inpcbtable_mtx);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index e5fc85d80d6..d3d79872ed3 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.113 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.114 2018/10/04 17:33:41 bluhm Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -149,7 +149,6 @@ rip_input(struct mbuf **mp, int *offp, int proto, int af)
}
#endif
NET_ASSERT_LOCKED();
- mtx_enter(&inpcbtable_mtx);
TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) {
if (inp->inp_socket->so_state & SS_CANTRCVMORE)
continue;
@@ -189,8 +188,6 @@ rip_input(struct mbuf **mp, int *offp, int proto, int af)
}
last = inp;
}
- mtx_leave(&inpcbtable_mtx);
-
if (last) {
if (last->inp_flags & INP_CONTROLOPTS ||
last->inp_socket->so_options & SO_TIMESTAMP)
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 15548a154bb..f1aa5b058f1 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_subr.c,v 1.173 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.174 2018/10/04 17:33:41 bluhm Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@@ -520,9 +520,7 @@ tcp_close(struct tcpcb *tp)
/* Free tcpcb after all pending timers have been run. */
TCP_TIMER_ARM(tp, TCPT_REAPER, 0);
- mtx_enter(&inp->inp_mtx);
inp->inp_ppcb = NULL;
- mtx_leave(&inp->inp_mtx);
soisdisconnected(so);
in_pcbdetach(inp);
return (NULL);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index adb4881940b..b2f5a6732d7 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.252 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.253 2018/10/04 17:33:41 bluhm Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -380,7 +380,6 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af)
*/
last = NULL;
NET_ASSERT_LOCKED();
- mtx_enter(&inpcbtable_mtx);
TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) {
if (inp->inp_socket->so_state & SS_CANTRCVMORE)
continue;
@@ -456,7 +455,6 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af)
SO_REUSEADDR)) == 0)
break;
}
- mtx_leave(&inpcbtable_mtx);
if (last == NULL) {
/*
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 2f56401b029..0100c9e28e5 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_pcb.c,v 1.107 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: in6_pcb.c,v 1.108 2018/10/04 17:33:41 bluhm Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -411,8 +411,6 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst,
errno = inet6ctlerrmap[cmd];
rdomain = rtable_l2(rtable);
- KERNEL_LOCK();
- mtx_enter(&inpcbtable_mtx);
TAILQ_FOREACH_SAFE(inp, &table->inpt_queue, inp_queue, ninp) {
if ((inp->inp_flags & INP_IPV6) == 0)
continue;
@@ -486,18 +484,9 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst,
}
do_notify:
nmatch++;
- /*
- * The notify functions may grab the kernel lock. Sometimes
- * we already hold the kernel lock when we acquire the pcb
- * mutex. So do an extra kernel lock before the mutex outside
- * of this loop. XXXSMP
- */
if (notify)
(*notify)(inp, errno);
}
- mtx_leave(&inpcbtable_mtx);
- KERNEL_UNLOCK();
-
return (nmatch);
}
@@ -512,7 +501,6 @@ in6_pcbhashlookup(struct inpcbtable *table, const struct in6_addr *faddr,
u_int rdomain;
rdomain = rtable_l2(rtable);
- mtx_enter(&inpcbtable_mtx);
head = in6_pcbhash(table, rdomain, faddr, fport, laddr, lport);
LIST_FOREACH(inp, head, inp_hash) {
if (!(inp->inp_flags & INP_IPV6))
@@ -533,7 +521,6 @@ in6_pcbhashlookup(struct inpcbtable *table, const struct in6_addr *faddr,
break;
}
}
- mtx_leave(&inpcbtable_mtx);
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: faddr= fport=%d laddr= lport=%d rdom=%u\n",
@@ -584,7 +571,6 @@ in6_pcblookup_listen(struct inpcbtable *table, struct in6_addr *laddr,
#endif
rdomain = rtable_l2(rtable);
- mtx_enter(&inpcbtable_mtx);
head = in6_pcbhash(table, rdomain, &zeroin6_addr, 0, key1, lport);
LIST_FOREACH(inp, head, inp_hash) {
if (!(inp->inp_flags & INP_IPV6))
@@ -617,7 +603,6 @@ in6_pcblookup_listen(struct inpcbtable *table, struct in6_addr *laddr,
LIST_REMOVE(inp, inp_hash);
LIST_INSERT_HEAD(head, inp, inp_hash);
}
- mtx_leave(&inpcbtable_mtx);
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: laddr= lport=%d rdom=%u\n",
diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c
index 1c9933f2365..2c60fe91f84 100644
--- a/sys/netinet6/ip6_divert.c
+++ b/sys/netinet6/ip6_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_divert.c,v 1.57 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.58 2018/10/04 17:33:41 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -190,12 +190,10 @@ divert6_packet(struct mbuf *m, int dir, u_int16_t divert_port)
return (0);
}
- mtx_enter(&inpcbtable_mtx);
TAILQ_FOREACH(inp, &divb6table.inpt_queue, inp_queue) {
if (inp->inp_lport == divert_port)
break;
}
- mtx_leave(&inpcbtable_mtx);
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index b3b140fda82..ea5429e4e1a 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip6.c,v 1.131 2018/09/20 18:59:10 bluhm Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.132 2018/10/04 17:33:41 bluhm Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@@ -158,7 +158,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
}
#endif
NET_ASSERT_LOCKED();
- mtx_enter(&inpcbtable_mtx);
TAILQ_FOREACH(in6p, &rawin6pcbtable.inpt_queue, inp_queue) {
if (in6p->inp_socket->so_state & SS_CANTRCVMORE)
continue;
@@ -178,10 +177,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, *offp,
sizeof(*icmp6));
- if (icmp6 == NULL) {
- mtx_leave(&inpcbtable_mtx);
+ if (icmp6 == NULL)
return IPPROTO_DONE;
- }
if (ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type,
in6p->inp_icmp6filt))
continue;
@@ -215,8 +212,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
}
last = in6p;
}
- mtx_leave(&inpcbtable_mtx);
-
if (last) {
if (last->inp_flags & IN6P_CONTROLOPTS)
ip6_savecontrol(last, m, &opts);