summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorBobby Eshleman <bobby.eshleman@bytedance.com>2023-03-29 16:51:58 +0000
committerDavid S. Miller <davem@davemloft.net>2023-03-31 08:58:13 +0100
commitf9d2b1e146e0f82f3d04629afd92698522058361 (patch)
tree888c3af527b7ce0888705db09ba6a029fd9f94b6 /net
parent6b36d68cc9bb1fc85bbe54ebe2eb6b2c3beec73d (diff)
downloadlwn-f9d2b1e146e0f82f3d04629afd92698522058361.tar.gz
lwn-f9d2b1e146e0f82f3d04629afd92698522058361.zip
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 <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>
Diffstat (limited to 'net')
-rw-r--r--net/vmw_vsock/virtio_transport_common.c10
1 files changed, 10 insertions, 0 deletions
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);