Skip to content

Commit

Permalink
vsock/virtio: initialize the_virtio_vsock before using VQs
Browse files Browse the repository at this point in the history
commit 53b08c4 upstream.

Once VQs are filled with empty buffers and we kick the host, it can send
connection requests. If the_virtio_vsock is not initialized before,
replies are silently dropped and do not reach the host.

virtio_transport_send_pkt() can queue packets once the_virtio_vsock is
set, but they won't be processed until vsock->tx_run is set to true. We
queue vsock->send_pkt_work when initialization finishes to send those
packets queued earlier.

Fixes: 0deab08 ("vsock/virtio: use RCU to avoid use-after-free on the_virtio_vsock")
Signed-off-by: Alexandru Matei <alexandru.matei@uipath.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20231024191742.14259-1-alexandru.matei@uipath.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
alex-matei authored and gregkh committed Nov 2, 2023
1 parent 7efb541 commit e83bce6
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion net/vmw_vsock/virtio_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,11 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock)

virtio_device_ready(vdev);

return 0;
}

static void virtio_vsock_vqs_start(struct virtio_vsock *vsock)
{
mutex_lock(&vsock->tx_lock);
vsock->tx_run = true;
mutex_unlock(&vsock->tx_lock);
Expand All @@ -569,7 +574,16 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock)
vsock->event_run = true;
mutex_unlock(&vsock->event_lock);

return 0;
/* virtio_transport_send_pkt() can queue packets once
* the_virtio_vsock is set, but they won't be processed until
* vsock->tx_run is set to true. We queue vsock->send_pkt_work
* when initialization finishes to send those packets queued
* earlier.
* We don't need to queue the other workers (rx, event) because
* as long as we don't fill the queues with empty buffers, the
* host can't send us any notification.
*/
queue_work(virtio_vsock_workqueue, &vsock->send_pkt_work);
}

static void virtio_vsock_vqs_del(struct virtio_vsock *vsock)
Expand Down Expand Up @@ -664,6 +678,7 @@ static int virtio_vsock_probe(struct virtio_device *vdev)
goto out;

rcu_assign_pointer(the_virtio_vsock, vsock);
virtio_vsock_vqs_start(vsock);

mutex_unlock(&the_virtio_vsock_mutex);

Expand Down Expand Up @@ -736,6 +751,7 @@ static int virtio_vsock_restore(struct virtio_device *vdev)
goto out;

rcu_assign_pointer(the_virtio_vsock, vsock);
virtio_vsock_vqs_start(vsock);

out:
mutex_unlock(&the_virtio_vsock_mutex);
Expand Down

0 comments on commit e83bce6

Please sign in to comment.