On Tue, Aug 25, 2026 at 5:40 PM Daehyeon Ko <[email protected]> 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 <[email protected]> > Closes: > https://lore.kernel.org/netdev/[email protected]/ > Cc: [email protected] > Suggested-by: Stefano Garzarella <[email protected]> > Suggested-by: Paolo Abeni <[email protected]> > Assisted-by: Codex:gpt-5.6-sol > Signed-off-by: Daehyeon Ko <[email protected]>
Reviewed-by: Vishnu Dasa <[email protected]> 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
smime.p7s
Description: S/MIME Cryptographic Signature

