From: Daehyeon Ko <4ncienth@gmail.com>
To: netdev@vger.kernel.org
Cc: Stefan Hajnoczi <stefanha@redhat.com>,
Stefano Garzarella <sgarzare@redhat.com>,
Bobby Eshleman <bobbyeshleman@gmail.com>,
virtualization@lists.linux.dev, kvm@vger.kernel.org
Subject: [PATCH net v2] vsock/virtio: validate packet source for connected sockets
Date: Thu, 20 Aug 2026 09:15:17 +0900 [thread overview]
Message-ID: <20260820001517.2148196-1-4ncienth@gmail.com> (raw)
virtio_transport_recv_pkt() looks up sockets first by the full source and
destination tuple, then by destination only in the bound table. The
fallback is needed for listening and connecting sockets, but sockets remain
in the bound table after connect(), so it can also return a non-listening
socket.
The fallback does not validate the source address. In TCP_SYN_SENT, a
RESPONSE from an unrelated source can transition the victim socket to
TCP_ESTABLISHED while its stored remote address remains unchanged.
Subsequent RW packets from that source are delivered through the same
destination-only fallback.
This was reproduced with capability-empty processes under different UIDs.
The attacker discovered the target tuple through unprivileged AF_VSOCK
sock_diag and caused the victim socket to read 16 attacker-chosen bytes;
the intended peer-side socket read 0 of those 16 bytes.
After lock_sock(), reject packets for non-listening sockets unless their
source port matches the stored remote port. Require the CID to match too,
except that the loopback transport uses VMADDR_CID_LOCAL as the packet
source for connections addressed through its valid CID aliases.
Fixes: 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko")
Closes: https://lore.kernel.org/netdev/20260813121236.2328599-1-4ncienth@gmail.com/
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
---
Changes in v2:
- Preserve valid loopback CID aliases by matching the source port and
accepting VMADDR_CID_LOCAL only for the loopback transport.
- Rewrite the commit message and receive-path comment for clarity.
v1: https://lore.kernel.org/netdev/20260813121236.2328599-1-4ncienth@gmail.com/
net/vmw_vsock/virtio_transport_common.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 8becad812..d8990f5f6 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -1764,6 +1764,21 @@ static bool virtio_transport_valid_type(u16 type)
(type == VIRTIO_VSOCK_TYPE_SEQPACKET);
}
+static bool virtio_transport_source_matches(const struct virtio_transport *t,
+ const struct sockaddr_vm *src,
+ const struct sockaddr_vm *remote)
+{
+ if (src->svm_port != remote->svm_port)
+ return false;
+
+ if (src->svm_cid == remote->svm_cid)
+ return true;
+
+ /* The loopback transport represents its peer as VMADDR_CID_LOCAL. */
+ return t->transport.get_local_cid() == VMADDR_CID_LOCAL &&
+ src->svm_cid == VMADDR_CID_LOCAL;
+}
+
/* We are under the virtio-vsock's vsock->rx_lock or vhost-vsock's vq->mutex
* lock.
*/
@@ -1823,10 +1838,15 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
lock_sock(sk);
/* Check if sk has been closed or assigned to another transport before
- * lock_sock (note: listener sockets are not assigned to any transport)
+ * lock_sock (note: listener sockets are not assigned to any transport).
+ * The bound-table fallback matches only the destination, so reject packets
+ * from a peer other than the one stored in the socket.
*/
if (sock_flag(sk, SOCK_DONE) ||
- (sk->sk_state != TCP_LISTEN && vsk->transport != &t->transport)) {
+ (sk->sk_state != TCP_LISTEN &&
+ (vsk->transport != &t->transport ||
+ !virtio_transport_source_matches(t, &src,
+ &vsk->remote_addr)))) {
(void)virtio_transport_reset_no_sock(t, skb, net);
release_sock(sk);
sock_put(sk);
base-commit: e2466392a0b8496000e12181cb1ee1535eb0da25
--
2.54.0
reply other threads:[~2026-08-20 0:16 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260820001517.2148196-1-4ncienth@gmail.com \
--to=4ncienth@gmail.com \
--cc=bobbyeshleman@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=sgarzare@redhat.com \
--cc=stefanha@redhat.com \
--cc=virtualization@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.