[PATCH RFC net v2 0/3] vsock/virtio: don't let sockets send from another local CID
From: Yiran Qiu
Date: Fri Oct 30 2026 - 02:47:15 EST
The virtio transports send every packet from the transport's CID, so a
socket bound to another local CID sends from another socket's address.
Patch 1 refuses connect() on such a socket; patches 2 and 3 close two
other ways a socket can send from another address or have its local
CID changed.
I'm sending this as an RFC because one problem is still open. Over
vsock_loopback, a socket bound to (VMADDR_CID_LOCAL, P) sends from the
same address as the children of a listener on (guest CID, P) -- or, on
a host, on (VMADDR_CID_HOST, P) -- and vsock_check_source()
(dee44f41f206) accepts packets from either one as coming from the
peer. So either one can shut down or stall the other's connections,
including those of clients that never called bind(). Making
vsock_loopback send from the bound CID would fix this and make patch 1
unnecessary for loopback. Would you prefer that, or these patches as
they are?
Changes in v2:
- New approach. v1 made bind() treat the same port on two local CIDs
as a conflict, but as the Sashiko review pointed out, its alias list
missed VMADDR_CID_HOST and did not handle guest->host transports
without a CID. I reproduced both gaps. v2 leaves bind() alone.
- Patches 2 and 3 are new.
- Only the virtio transports change, vsock_loopback included. VMCI
picks its source context by route (a nested VMware guest reaches its
VMs from VMADDR_CID_HOST), and hv_sock has no CIDs.
- v1: https://patch.msgid.link/20261028065231.655701-1-eritque-arcus@xxxxxxxxx
I tested on net 4dca97647a3e (net/vmw_vsock is unchanged through
5838f10563d5) under QEMU/KVM with vsock_loopback built in, in four
setups: guests with vhost_vsock, with and without the virtio-vsock
device; a guest with the device but no vhost_vsock; and a host with
vhost_vsock and no virtio transport. The table shows where each
problem reproduces as the patches are applied one at a time ("no dev"
is the guest without the device):
base +1 +1+2 +1+2+3
connect() reset all fixed fixed fixed
credit update stall all all fixed fixed
rebind to CID ANY no dev, host no dev, host no dev fixed
vsock_test passes at every step, and no connect() that used to succeed
is now refused. I have not tested VMware, Hyper-V or nested setups,
nor run with KASAN, and there is no vsock_test case yet; I can add one.
The patch 1 problem was found with afb-afl, an LLM-driven audit
pipeline, and this letter was drafted with Claude.
Yiran Qiu (3):
vsock/virtio: refuse connect() from a CID the transport does not own
vsock/virtio: send credit updates only while connecting or connected
vsock/virtio: only update a socket's local CID to the transport's CID
net/vmw_vsock/virtio_transport_common.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
--
2.56.0