Use `sb_mtx' to protect `so_rcv' receive buffer of unix(4) sockets.
authormvs <mvs@openbsd.org>
Tue, 26 Mar 2024 09:46:47 +0000 (09:46 +0000)
committermvs <mvs@openbsd.org>
Tue, 26 Mar 2024 09:46:47 +0000 (09:46 +0000)
commit02a827120adb2d89281e9b7a793e5d4eb9e5b56e
treec24d003df593f00d7d2bc3582c6aea02983c4774
parent40ae7d6bc66d03e54ad7f33a82a1e22aa4b447ca
Use `sb_mtx' to protect `so_rcv' receive buffer of unix(4) sockets.

This makes re-locking unnecessary in the uipc_*send() paths, because
it's enough to lock one socket to prevent peer from concurrent
disconnection. As the little bonus, one  unix(4) socket can perform
simultaneous transmission and reception with one exception for
uipc_rcvd(), which still requires the re-lock for connection oriented
sockets.

The socket lock is not held while filt_soread() and filt_soexcept()
called from uipc_*send() through sorwakeup(). However, the unlocked
access to the `so_options', `so_state' and `so_error' is fine.

The receiving socket can't be or became listening socket. It also can't
be disconnected concurrently. This makes immutable SO_ACCEPTCONN,
SS_ISDISCONNECTED and SS_ISCONNECTED bits which are clean and set
respectively.

`so_error' is set on the peer sockets only by unp_detach(), which also
can't be called concurrently on sending socket.

This is also true for filt_fiforead() and filt_fifoexcept(). For other
callers like kevent(2) or doaccept() the socket lock is still held.

ok bluhm
sys/kern/sys_socket.c
sys/kern/uipc_socket.c
sys/kern/uipc_socket2.c
sys/kern/uipc_usrreq.c
sys/miscfs/fifofs/fifo_vnops.c
sys/sys/socketvar.h