Use vnode(9) lock to protect `v_socket' dereference.
authormvs <mvs@openbsd.org>
Thu, 11 Nov 2021 17:20:02 +0000 (17:20 +0000)
committermvs <mvs@openbsd.org>
Thu, 11 Nov 2021 17:20:02 +0000 (17:20 +0000)
commit5c5d25f4a2ae9342ec90ef863d12651d9c5d1619
tree74b4b193a3120d78b3b3c33c899b6b3e49f76da9
parentcb72bf000c026f7cc71cfecec5b025011e32f4d2
Use vnode(9) lock to protect `v_socket' dereference.

The bind(2)ed UNIX socket hat the reference from the file system layer.
When we bind(2) such socket we link it to `v_socket' of associated
vnode(9). When we connect(2) to the socket we previously bind(2)ed we
finding it by namei(9) and obtain it's reference through `v_socket'. When
we close(2) this socket we set `v_socket' of associated vnode(9) to NULL.

This time the global `unp_lock' rwlock(9) protects the whole layer and the
dereference of `v_socket'. With the upcoming fine grained locking diffs it
will be replaced by per-socket solock(). So the dereference of `v_socket'
will be unsafe because it will be unlocked and has no extra reference in
the associated file descriptor.

Actually we have vnode(9) locked while we perform unp_bind() and
unp_connect() paths so use vnode(9) lock in the unp_detach() path too when
we disconnect dying socket from the associated vnode(9). This makes
`v_socket' locking consistent because `v_socket' relies to vnode(9) layer.
Also this makes `v_socket' dereference safe for the upcoming fine grained
locking diffs.

Do `v_socket' unlinking before `unp_refs' list cleanup to prevent
concurrent connections while dying socket `so' is unlocked.

ok bluhm@
sys/kern/uipc_usrreq.c