Date: Thu, 18 Jun 2009 20:56:22 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r194460 - head/sys/kern Message-ID: <200906182056.n5IKuMdw022573@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Thu Jun 18 20:56:22 2009 New Revision: 194460 URL: http://svn.freebsd.org/changeset/base/194460 Log: Fix a deadlock in the getpeername() method for UNIX domain sockets. Instead of locking the local unp followed by the remote unp, use the same locking model as accept() and read lock the global link lock followed by the remote unp while fetching the remote sockaddr. Reported by: Mel Flynn mel.flynn of mailing.thruhere.net Reviewed by: rwatson MFC after: 1 week Modified: head/sys/kern/uipc_usrreq.c Modified: head/sys/kern/uipc_usrreq.c ============================================================================== --- head/sys/kern/uipc_usrreq.c Thu Jun 18 20:42:37 2009 (r194459) +++ head/sys/kern/uipc_usrreq.c Thu Jun 18 20:56:22 2009 (r194460) @@ -671,7 +671,7 @@ uipc_peeraddr(struct socket *so, struct KASSERT(unp != NULL, ("uipc_peeraddr: unp == NULL")); *nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK); - UNP_PCB_LOCK(unp); + UNP_LINK_RLOCK(); /* * XXX: It seems that this test always fails even when connection is * established. So, this else clause is added as workaround to @@ -681,7 +681,7 @@ uipc_peeraddr(struct socket *so, struct if (unp2 != NULL) { UNP_PCB_LOCK(unp2); if (unp2->unp_addr != NULL) - sa = (struct sockaddr *) unp->unp_conn->unp_addr; + sa = (struct sockaddr *) unp2->unp_addr; else sa = &sun_noname; bcopy(sa, *nam, sa->sa_len); @@ -690,7 +690,7 @@ uipc_peeraddr(struct socket *so, struct sa = &sun_noname; bcopy(sa, *nam, sa->sa_len); } - UNP_PCB_UNLOCK(unp); + UNP_LINK_RUNLOCK(); return (0); } @@ -850,7 +850,7 @@ uipc_send(struct socket *so, int flags, * return the slightly counter-intuitive but otherwise * correct error that the socket is not connected. * - * Locking here must be done carefully: the inkage lock + * Locking here must be done carefully: the linkage lock * prevents interconnections between unpcbs from changing, so * we can traverse from unp to unp2 without acquiring unp's * lock. Socket buffer locks follow unpcb locks, so we can
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906182056.n5IKuMdw022573>