path: root/sys/sys/unpcb.h
diff options
authorMark Johnston <markj@FreeBSD.org>2020-09-15 19:23:22 +0000
committerMark Johnston <markj@FreeBSD.org>2020-09-15 19:23:22 +0000
commitccdadf1a9bb64156e4a62bb6207c37b841467cb7 (patch)
tree98a11c6ec3562589d775a8ac5e1388508354a2c1 /sys/sys/unpcb.h
parented92e1c78cba5edeb971390aab10c74ab3ad8519 (diff)
Simplify unix socket connection peer locking.
unp_pcb_owned_lock2() has some sharp edges and forces callers to deal with a bunch of cases. Simplify it: - Rename to unp_pcb_lock_peer(). - Return the connected peer instead of forcing callers to load it beforehand. - Handle self-connected sockets. - In unp_connectat(), just lock the accept socket directly. It should not be possible for the nascent socket to participate in any other lock orders. - Get rid of connect_internal(). It does not provide any useful checking anymore. - Block in unp_connectat() when a different thread is concurrently attempting to lock both sides of a connection. This provides simpler semantics for callers of unp_pcb_lock_peer(). - Make unp_connectat() return EISCONN if the socket is already connected. This fixes a race[1] when multiple threads attempt to connect() to different addresses using the same datagram socket. Upper layers will disconnect a connected datagram socket before calling the protocol connect's method, but there is no synchronization between this and protocol-layer code. Reported by: syzkaller [1] Tested by: pho Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D26299
Notes: svn path=/head/; revision=365764
Diffstat (limited to 'sys/sys/unpcb.h')
1 files changed, 2 insertions, 0 deletions
diff --git a/sys/sys/unpcb.h b/sys/sys/unpcb.h
index abc8586b4e69..50a8beba8ec1 100644
--- a/sys/sys/unpcb.h
+++ b/sys/sys/unpcb.h
@@ -85,6 +85,7 @@ struct unpcb {
struct sockaddr_un *unp_addr; /* (p) bound address of socket */
struct socket *unp_socket; /* (c) pointer back to socket */
/* Cache line 2 */
+ u_int unp_pairbusy; /* (p) threads acquiring peer locks */
struct vnode *unp_vnode; /* (p) associated file if applicable */
struct xucred unp_peercred; /* (p) peer credentials if applicable */
LIST_ENTRY(unpcb) unp_reflink; /* (l) link in unp_refs list */
@@ -117,6 +118,7 @@ struct unpcb {
#define UNP_CONNECTING 0x010 /* Currently connecting. */
#define UNP_BINDING 0x020 /* Currently binding. */
+#define UNP_WAITING 0x040 /* Peer state is changing. */
* Flags in unp_gcflag.