vsock_bpf_recvmsg() holds lock_sock() while it sleeps for data, so the transport's delivery worker, which needs that lock to queue the data, deadlocks with the reader. Patch 1 releases the lock around the wait and makes the wait loop with the exit conditions of the native path. Patch 2 handles the reads that should never reach the sockmap wait: len == 0, MSG_ERRQUEUE and MSG_OOB.
Not addressed here, as in v3: data that sits only in psock->ingress_skb, and READ_ONCE()/WRITE_ONCE() for the lockless accesses; both are left for separate patches. Not run: the ns_* tests of vmtest.sh (they need root on the host); the reproducers ran in a guest over virtio-vsock (PCI) and vsock-loopback only. The deadlock and the MSG_ERRQUEUE case were found with the help of Anthropic's Claude; the other cases come from the netdev Sashiko review. The reproducers are available on request. Changes in v4: - 1/2: comment why the wait stops on sk_err and why it checks signal_pending() (Stefano). - 1/2: one data <= 0 check in vsock_bpf_recvmsg() (Stefano). - 1/2: say why this is one patch and how non-blocking reads change (Stefano). - 2/2: say that MSG_ERRQUEUE consumed stream bytes and why the checks come in this order (Stefano). - Shorter commit messages. - Rebase onto current net. - Retested, with a new reproducer for a dataless wakeup during a timed wait. - Link to v3: https://patch.msgid.link/[email protected] Changes in v3: - Split into two patches (Michal): 1/2 releases the lock and loops in the wait, 2/2 handles len == 0, MSG_ERRQUEUE and MSG_OOB. - 1/2: also end the wait once the socket is no longer TCP_ESTABLISHED (0 with SOCK_DONE, else -ENOTCONN, as __vsock_connectible_recvmsg() does), so a reset connection whose error was read with SO_ERROR no longer waits out the timeout (Sashiko review of v2). - 2/2: reject MSG_OOB with -EOPNOTSUPP before the len == 0 check, as unix_bpf does; this also stops MSG_OOB from consuming ordinary bytes (Sashiko review of v2). - Stefano's Acked-by on v1 is not carried: neither patch matches v1. - Drop the Assisted-by trailer (removed upstream); tool use is disclosed above instead. - Rebase onto current net. - Link to v2: https://lore.kernel.org/netdev/[email protected]/ Changes in v2: - Make vsock_msg_wait_data() loop, check sk_err and the peer SEND_SHUTDOWN, and add the len == 0 guard (Sashiko review of v1); route MSG_ERRQUEUE to the native path ahead of the guard. - Link to v1: https://lore.kernel.org/netdev/[email protected]/ --- Jerome Mohm (2): vsock/bpf: release sock lock while waiting for data in recvmsg vsock/bpf: fix zero-length, MSG_OOB and MSG_ERRQUEUE reads in recvmsg net/vmw_vsock/vsock_bpf.c | 77 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 14 deletions(-) --- base-commit: 6d2cf411aba2aa0bd641b49be5b1964ac5097a50 change-id: 20261001-kbh3-1-022-fix-v2-e3f14290641a Best regards, -- Jerome Mohm <[email protected]>
