When calling connect to change the CID of a vsock, the loopback worker for the VIRTIO_VSOCK_OP_RST command is invoked. During this process, vsock_stream_has_data() calls vsk->transport->stream_has_data(). However, a null-ptr-deref occurs because vsk->transport was set to NULL in vsock_deassign_transport(). cpu0 cpu1 socket(A) bind(A, VMADDR_CID_LOCAL) vsock_bind() listen(A) vsock_listen() socket(B) connect(B, VMADDR_CID_LOCAL) connect(B, VMADDR_CID_HYPERVISOR) vsock_connect(B) lock_sock(sk); vsock_assign_transport() virtio_transport_release() virtio_transport_close() virtio_transport_shutdown() virtio_transport_send_pkt_info() vsock_loopback_send_pkt(VIRTIO_VSOCK_OP_SHUTDOWN) queue_work(vsock_loopback_work) vsock_deassign_transport() vsk->transport = NULL; vsock_loopback_work() virtio_transport_recv_pkt(VIRTIO_VSOCK_OP_SHUTDOWN) virtio_transport_recv_connected() virtio_transport_reset() virtio_transport_send_pkt_info() vsock_loopback_send_pkt(VIRTIO_VSOCK_OP_RST) queue_work(vsock_loopback_work) vsock_loopback_work() virtio_transport_recv_pkt(VIRTIO_VSOCK_OP_RST) virtio_transport_recv_disconnecting() virtio_transport_do_close() vsock_stream_has_data() vsk->transport->stream_has_data(vsk); // null-ptr-deref To resolve this issue, add a check for vsk->transport, similar to functions like vsock_send_shutdown(). Fixes: fe502c4a38d9 ("vsock: add 'transport' member in the struct vsock_sock") Signed-off-by: Hyunwoo Kim <v4bel@xxxxxxxxx> Signed-off-by: Wongi Lee <qwerty@xxxxxxxxx> --- net/vmw_vsock/af_vsock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 5cf8109f672a..a0c008626798 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -870,6 +870,9 @@ EXPORT_SYMBOL_GPL(vsock_create_connected); s64 vsock_stream_has_data(struct vsock_sock *vsk) { + if (!vsk->transport) + return 0; + return vsk->transport->stream_has_data(vsk); } EXPORT_SYMBOL_GPL(vsock_stream_has_data); -- 2.34.1