Skip site navigation (1)Skip section navigation (2)
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>