diff options
author | 2018-10-04 17:33:40 +0000 | |
---|---|---|
committer | 2018-10-04 17:33:40 +0000 | |
commit | 3022661327119d66e40f035bd4a885e7569f1e0e (patch) | |
tree | 172d93471cc2c54a1434d0ab548fc8d5e68022f3 | |
parent | Plug TLS context leak in nc(1) server and client mode. Move (diff) | |
download | wireguard-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.c | 37 | ||||
-rw-r--r-- | sys/netinet/in_pcb.c | 53 | ||||
-rw-r--r-- | sys/netinet/in_pcb.h | 35 | ||||
-rw-r--r-- | sys/netinet/ip_divert.c | 4 | ||||
-rw-r--r-- | sys/netinet/raw_ip.c | 5 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 4 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 4 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.c | 17 | ||||
-rw-r--r-- | sys/netinet6/ip6_divert.c | 4 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 9 |
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); |