summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2017-02-09 11:18:56 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2017-02-09 11:18:56 +0000
commite8fa3132c10923ee7617f115984c895e20a7e65e (patch)
tree9ebc0bdcdc69de6bcde2a1c9f639e357ad1d617a
parent3e39706e91813f95f40244a2babd629f42b32565 (diff)
Temporarily grab the NET_LOCK() around soisdisconnected().
This makes a (wrong) assert disappear and makes sure we hack to avoid a recursion in the upcall case still work. The real solution to this problem is to not grab the NET_LOCK() before entering uipc_usrreq(). Issue reported by dtucker@
-rw-r--r--sys/kern/uipc_usrreq.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index b9cc8130d7d..0c1819b5c35 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_usrreq.c,v 1.114 2017/02/09 10:40:57 mpi Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.115 2017/02/09 11:18:55 mpi Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
@@ -398,6 +398,8 @@ unp_detach(struct unpcb *unp)
{
struct vnode *vp;
+ NET_ASSERT_UNLOCKED();
+
LIST_REMOVE(unp, unp_link);
if (unp->unp_vnode) {
unp->unp_vnode->v_socket = NULL;
@@ -409,7 +411,10 @@ unp_detach(struct unpcb *unp)
unp_disconnect(unp);
while (!SLIST_EMPTY(&unp->unp_refs))
unp_drop(SLIST_FIRST(&unp->unp_refs), ECONNRESET);
+ /* XXXSMP The assert is wrong */
+ rw_enter_write(&netlock);
soisdisconnected(unp->unp_socket);
+ rw_exit_write(&netlock);
unp->unp_socket->so_pcb = NULL;
m_freem(unp->unp_addr);
free(unp, M_PCB, sizeof *unp);