From owner-svn-src-all@freebsd.org Thu May 24 21:13:47 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4B19DEFE73B; Thu, 24 May 2018 21:13:47 +0000 (UTC) (envelope-from mmacy@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EF9AB848C2; Thu, 24 May 2018 21:13:46 +0000 (UTC) (envelope-from mmacy@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D13CA17A24; Thu, 24 May 2018 21:13:46 +0000 (UTC) (envelope-from mmacy@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w4OLDkEr014694; Thu, 24 May 2018 21:13:46 GMT (envelope-from mmacy@FreeBSD.org) Received: (from mmacy@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w4OLDk6f014693; Thu, 24 May 2018 21:13:46 GMT (envelope-from mmacy@FreeBSD.org) Message-Id: <201805242113.w4OLDk6f014693@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mmacy set sender to mmacy@FreeBSD.org using -f From: Matt Macy Date: Thu, 24 May 2018 21:13:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r334185 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: mmacy X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 334185 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 May 2018 21:13:47 -0000 Author: mmacy Date: Thu May 24 21:13:46 2018 New Revision: 334185 URL: https://svnweb.freebsd.org/changeset/base/334185 Log: AF_UNIX: It is possible for UNIX datagram sockets to be connected to themselves. The updated code assumed that that could not happen and would try to lock the unp mutex twice. There may be a lingering issue here but this fixes it for the reporter. PR: 228458 Reported by: marieheleneka at gmail.com Modified: head/sys/kern/uipc_usrreq.c Modified: head/sys/kern/uipc_usrreq.c ============================================================================== --- head/sys/kern/uipc_usrreq.c Thu May 24 21:11:38 2018 (r334184) +++ head/sys/kern/uipc_usrreq.c Thu May 24 21:13:46 2018 (r334185) @@ -722,7 +722,9 @@ uipc_close(struct socket *so) } unp2 = unp->unp_conn; unp_pcb_hold(unp); - if (unp2 != NULL) { + if (__predict_false(unp == unp2)) { + unp_disconnect(unp, unp2); + } else if (unp2 != NULL) { unp_pcb_hold(unp2); unp_pcb_owned_lock2(unp, unp2, freed); unp_disconnect(unp, unp2); @@ -747,9 +749,13 @@ uipc_connect2(struct socket *so1, struct socket *so2) KASSERT(unp != NULL, ("uipc_connect2: unp == NULL")); unp2 = so2->so_pcb; KASSERT(unp2 != NULL, ("uipc_connect2: unp2 == NULL")); - unp_pcb_lock2(unp, unp2); + if (unp != unp2) + unp_pcb_lock2(unp, unp2); + else + UNP_PCB_LOCK(unp); error = unp_connect2(so1, so2, PRU_CONNECT2); - UNP_PCB_UNLOCK(unp2); + if (unp != unp2) + UNP_PCB_UNLOCK(unp2); UNP_PCB_UNLOCK(unp); return (error); } @@ -783,29 +789,30 @@ uipc_detach(struct socket *so) mtx_lock(vplock); } UNP_PCB_LOCK(unp); - if ((unp2 = unp->unp_conn) != NULL) { - unp_pcb_owned_lock2(unp, unp2, freeunp); - if (freeunp) - unp2 = NULL; - } if (unp->unp_vnode != vp && unp->unp_vnode != NULL) { if (vplock) mtx_unlock(vplock); UNP_PCB_UNLOCK(unp); - if (unp2) - UNP_PCB_UNLOCK(unp2); goto restart; } if ((unp->unp_flags & UNP_NASCENT) != 0) { - if (unp2) - UNP_PCB_UNLOCK(unp2); goto teardown; } if ((vp = unp->unp_vnode) != NULL) { VOP_UNP_DETACH(vp); unp->unp_vnode = NULL; } + if (__predict_false(unp == unp->unp_conn)) { + unp_disconnect(unp, unp); + unp2 = NULL; + goto connect_self; + } + if ((unp2 = unp->unp_conn) != NULL) { + unp_pcb_owned_lock2(unp, unp2, freeunp); + if (freeunp) + unp2 = NULL; + } unp_pcb_hold(unp); if (unp2 != NULL) { unp_pcb_hold(unp2); @@ -813,6 +820,7 @@ uipc_detach(struct socket *so) if (unp_pcb_rele(unp2) == 0) UNP_PCB_UNLOCK(unp2); } + connect_self: UNP_PCB_UNLOCK(unp); UNP_REF_LIST_LOCK(); while (!LIST_EMPTY(&unp->unp_refs)) { @@ -864,6 +872,10 @@ uipc_disconnect(struct socket *so) UNP_PCB_UNLOCK(unp); return (0); } + if (unp == unp2) { + if (unp_pcb_rele(unp) == 0) + UNP_PCB_UNLOCK(unp); + } unp_pcb_owned_lock2(unp, unp2, freed); if (__predict_false(freed)) { UNP_PCB_UNLOCK(unp); @@ -1925,7 +1937,9 @@ unp_drop(struct unpcb *unp) if (so) so->so_error = ECONNRESET; unp2 = unp->unp_conn; - if (unp2 != NULL) { + if (unp2 == unp) { + unp_disconnect(unp, unp2); + } else if (unp2 != NULL) { unp_pcb_hold(unp2); unp_pcb_owned_lock2(unp, unp2, freed); unp_disconnect(unp, unp2);