Re: [PATCH net v4 2/2] vsock/vmci: validate packet source for connected sockets

From: Vishnu Dasa

Date: Mon Aug 31 2026 - 18:33:51 EST


On Tue, Aug 25, 2026 at 5:40 PM Daehyeon Ko <4ncienth@xxxxxxxxx> wrote:
>
> vmci_transport_recv_stream_cb() looks up sockets first by the full source
> and destination tuple, then by destination only in the bound table. The
> fallback can select a non-listening socket without checking whether the
> packet came from its stored peer.
>
> This was reproduced with two VMCI contexts. A RST from the context not
> stored in a TCP_SYN_SENT socket reset that socket after it was selected by
> the destination-only lookup.
>
> VMCI can process notification packets in bottom-half context when the
> socket is not owned by user context, or defer packets to a workqueue. Use
> vsock_check_source() after taking the socket lock in the bottom-half path,
> and recheck after lock_sock() in the workqueue path. Listening sockets
> continue to accept packets from any source.
>
> Reply with a RST addressed from the received packet before dropping a
> source that fails validation. This preserves the existing reset behavior
> for bound non-listening and concurrently closed sockets without directing
> the reset to a connected socket's stored peer.
>
> Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
> Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
> Closes: https://lore.kernel.org/netdev/20260814121255.6B5001F000E9@xxxxxxxxxxxxxxx/
> Cc: stable@xxxxxxxxxxxxxxx
> Suggested-by: Stefano Garzarella <sgarzare@xxxxxxxxxx>
> Suggested-by: Paolo Abeni <pabeni@xxxxxxxxxx>
> Assisted-by: Codex:gpt-5.6-sol
> Signed-off-by: Daehyeon Ko <4ncienth@xxxxxxxxx>

Reviewed-by: Vishnu Dasa <vishnu.dasa@xxxxxxxxxxxx>

Thanks!

> ---
> net/vmw_vsock/vmci_transport.c | 34 ++++++++++++++++++++++++++++------
> 1 file changed, 28 insertions(+), 6 deletions(-)
>
> diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
> index 1c4ee039c..1f186e8f8 100644
> --- a/net/vmw_vsock/vmci_transport.c
> +++ b/net/vmw_vsock/vmci_transport.c
> @@ -680,11 +680,13 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
> struct vmci_transport_packet *pkt;
> struct vsock_sock *vsk;
> bool bh_process_pkt;
> + bool drop_pkt;
> int err;
>
> sk = NULL;
> err = VMCI_SUCCESS;
> bh_process_pkt = false;
> + drop_pkt = false;
>
> /* Ignore incoming packets from resources that aren't vsock
> * implementations.
> @@ -765,17 +767,29 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
> bh_lock_sock(sk);
>
> if (!sock_owned_by_user(sk)) {
> - /* The local context ID may be out of date, update it. */
> - vsk->local_addr.svm_cid = dst.svm_cid;
> + if (sk->sk_state != TCP_LISTEN &&
> + !vsock_check_source(vsk, &vmci_transport, &src)) {
> + drop_pkt = true;
> + err = VMCI_ERROR_NO_ACCESS;
> + } else {
> + /* The local context ID may be out of date, update it. */
> + vsk->local_addr.svm_cid = dst.svm_cid;
>
> - if (sk->sk_state == TCP_ESTABLISHED)
> - vmci_trans(vsk)->notify_ops->handle_notify_pkt(
> - sk, pkt, true, &dst, &src,
> - &bh_process_pkt);
> + if (sk->sk_state == TCP_ESTABLISHED)
> + vmci_trans(vsk)->notify_ops->handle_notify_pkt(sk, pkt, true,
> + &dst, &src,
> + &bh_process_pkt);
> + }
> }
>
> bh_unlock_sock(sk);
>
> + if (drop_pkt) {
> + if (vmci_transport_send_reset_bh(&dst, &src, pkt) < 0)
> + pr_err("unable to send reset\n");
> + goto out;
> + }
> +
> if (!bh_process_pkt) {
> struct vmci_transport_recv_pkt_info *recv_pkt_info;
>
> @@ -900,6 +914,7 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
> {
> struct vmci_transport_recv_pkt_info *recv_pkt_info;
> struct vmci_transport_packet *pkt;
> + struct sockaddr_vm src;
> struct sock *sk;
>
> recv_pkt_info =
> @@ -908,6 +923,12 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
> pkt = &recv_pkt_info->pkt;
>
> lock_sock(sk);
> + vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
> + if (sk->sk_state != TCP_LISTEN &&
> + !vsock_check_source(vsock_sk(sk), &vmci_transport, &src)) {
> + vmci_transport_reply_reset(pkt);
> + goto out;
> + }
>
> /* The local context ID may be out of date. */
> vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context;
> @@ -937,6 +958,7 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
> break;
> }
>
> +out:
> release_sock(sk);
> kfree(recv_pkt_info);
> /* Release reference obtained in the stream callback when we fetched

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature