From c684c14ce324d1f8ceffc390ee9c83ec899bda70 Mon Sep 17 00:00:00 2001 From: Matt Macy Date: Thu, 24 May 2018 18:22:13 +0000 Subject: [PATCH] AF_UNIX: evidently Samba likes to connect a unix socket to itself, fix locking --- sys/kern/uipc_usrreq.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 3fd8c5a68877..363bc4fb75cf 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1069,6 +1069,13 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, break; } } + if (__predict_false(unp == unp2)) { + if (unp->unp_socket == NULL) { + error = ENOTCONN; + break; + } + goto connect_self; + } unp_pcb_owned_lock2(unp, unp2, freed); if (__predict_false(freed)) { UNP_PCB_UNLOCK(unp); @@ -1088,6 +1095,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, error = ENOTCONN; break; } + connect_self: if (unp2->unp_flags & UNP_WANTCRED) control = unp_addsockcred(td, control); if (unp->unp_addr != NULL) @@ -1107,7 +1115,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, } if (nam != NULL) unp_disconnect(unp, unp2); - UNP_PCB_UNLOCK(unp2); + if (__predict_true(unp != unp2)) + UNP_PCB_UNLOCK(unp2); UNP_PCB_UNLOCK(unp); break; }