From f9d2b1e146e0f82f3d04629afd92698522058361 Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Wed, 29 Mar 2023 16:51:58 +0000 Subject: virtio/vsock: fix leaks due to missing skb owner This patch sets the skb owner in the recv and send path for virtio. For the send path, this solves the leak caused when virtio_transport_purge_skbs() finds skb->sk is always NULL and therefore never matches it with the current socket. Setting the owner upon allocation fixes this. For the recv path, this ensures correctness of accounting and also correct transfer of ownership in vsock_loopback (when skbs are sent from one socket and received by another). Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff") Signed-off-by: Bobby Eshleman Reported-by: Cong Wang Link: https://lore.kernel.org/all/ZCCbATwov4U+GBUv@pop-os.localdomain/ Reviewed-by: Stefano Garzarella Signed-off-by: David S. Miller --- net/vmw_vsock/virtio_transport_common.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'net/vmw_vsock') diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 37934dfe72f4..ee78b4082ef9 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -94,6 +94,11 @@ virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info, info->op, info->flags); + if (info->vsk && !skb_set_owner_sk_safe(skb, sk_vsock(info->vsk))) { + WARN_ONCE(1, "failed to allocate skb on vsock socket with sk_refcnt == 0\n"); + goto out; + } + return skb; out: @@ -1303,6 +1308,11 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, goto free_pkt; } + if (!skb_set_owner_sk_safe(skb, sk)) { + WARN_ONCE(1, "receiving vsock socket has sk_refcnt == 0\n"); + goto free_pkt; + } + vsk = vsock_sk(sk); lock_sock(sk); -- cgit v1.2.3-70-g09d2 From ffa5395a7901e83a68d88207c4592962906641bd Mon Sep 17 00:00:00 2001 From: Arseniy Krasnov Date: Fri, 31 Mar 2023 10:56:41 +0300 Subject: vsock/vmci: convert VMCI error code to -ENOMEM on send This adds conversion of VMCI specific error code to general -ENOMEM. It is needed, because af_vsock.c passes error value returned from transport to the user, which does not expect to get VMCI_ERROR_* values. Fixes: c43170b7e157 ("vsock: return errors other than -ENOMEM to socket") Signed-off-by: Arseniy Krasnov Reviewed-by: Vishnu Dasa Reviewed-by: Stefano Garzarella Signed-off-by: David S. Miller --- net/vmw_vsock/vmci_transport.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'net/vmw_vsock') diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 36eb16a40745..95cc4d79ba29 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -1842,7 +1842,13 @@ static ssize_t vmci_transport_stream_enqueue( struct msghdr *msg, size_t len) { - return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg, len, 0); + ssize_t err; + + err = vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg, len, 0); + if (err < 0) + err = -ENOMEM; + + return err; } static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk) -- cgit v1.2.3-70-g09d2