virtio/vsock: fix leaks due to missing skb owner
authorBobby Eshleman <bobby.eshleman@bytedance.com>
Wed, 29 Mar 2023 16:51:58 +0000 (16:51 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 31 Mar 2023 07:58:13 +0000 (08:58 +0100)
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 <bobby.eshleman@bytedance.com>
Reported-by: Cong Wang <xiyou.wangcong@gmail.com>
Link: https://lore.kernel.org/all/ZCCbATwov4U+GBUv@pop-os.localdomain/
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/vmw_vsock/virtio_transport_common.c

index 37934dfe72f456e4ea5d3bb21ef6a7feca9ab98a..ee78b4082ef95fe6277bef1fa2960fc9684b1fb3 100644 (file)
@@ -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);