Patch "virtio/vsock: Fix accept_queue memory leak" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    virtio/vsock: Fix accept_queue memory leak

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     virtio-vsock-fix-accept_queue-memory-leak.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit c8e2ffc96d27901bf54c3ec59b567b78033ce0bb
Author: Michal Luczaj <mhal@xxxxxxx>
Date:   Thu Nov 7 21:46:12 2024 +0100

    virtio/vsock: Fix accept_queue memory leak
    
    [ Upstream commit d7b0ff5a866724c3ad21f2628c22a63336deec3f ]
    
    As the final stages of socket destruction may be delayed, it is possible
    that virtio_transport_recv_listen() will be called after the accept_queue
    has been flushed, but before the SOCK_DONE flag has been set. As a result,
    sockets enqueued after the flush would remain unremoved, leading to a
    memory leak.
    
    vsock_release
      __vsock_release
        lock
        virtio_transport_release
          virtio_transport_close
            schedule_delayed_work(close_work)
        sk_shutdown = SHUTDOWN_MASK
    (!) flush accept_queue
        release
                                            virtio_transport_recv_pkt
                                              vsock_find_bound_socket
                                              lock
                                              if flag(SOCK_DONE) return
                                              virtio_transport_recv_listen
                                                child = vsock_create_connected
                                          (!)   vsock_enqueue_accept(child)
                                              release
    close_work
      lock
      virtio_transport_do_close
        set_flag(SOCK_DONE)
        virtio_transport_remove_sock
          vsock_remove_sock
            vsock_remove_bound
      release
    
    Introduce a sk_shutdown check to disallow vsock_enqueue_accept() during
    socket destruction.
    
    unreferenced object 0xffff888109e3f800 (size 2040):
      comm "kworker/5:2", pid 371, jiffies 4294940105
      hex dump (first 32 bytes):
        00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        28 00 0b 40 00 00 00 00 00 00 00 00 00 00 00 00  (..@............
      backtrace (crc 9e5f4e84):
        [<ffffffff81418ff1>] kmem_cache_alloc_noprof+0x2c1/0x360
        [<ffffffff81d27aa0>] sk_prot_alloc+0x30/0x120
        [<ffffffff81d2b54c>] sk_alloc+0x2c/0x4b0
        [<ffffffff81fe049a>] __vsock_create.constprop.0+0x2a/0x310
        [<ffffffff81fe6d6c>] virtio_transport_recv_pkt+0x4dc/0x9a0
        [<ffffffff81fe745d>] vsock_loopback_work+0xfd/0x140
        [<ffffffff810fc6ac>] process_one_work+0x20c/0x570
        [<ffffffff810fce3f>] worker_thread+0x1bf/0x3a0
        [<ffffffff811070dd>] kthread+0xdd/0x110
        [<ffffffff81044fdd>] ret_from_fork+0x2d/0x50
        [<ffffffff8100785a>] ret_from_fork_asm+0x1a/0x30
    
    Fixes: 3fe356d58efa ("vsock/virtio: discard packets only when socket is really closed")
    Reviewed-by: Stefano Garzarella <sgarzare@xxxxxxxxxx>
    Signed-off-by: Michal Luczaj <mhal@xxxxxxx>
    Signed-off-by: Paolo Abeni <pabeni@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index b22dc7bed2182..3bc573cbf8a6e 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -1220,6 +1220,14 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb,
 		return -ENOMEM;
 	}
 
+	/* __vsock_release() might have already flushed accept_queue.
+	 * Subsequent enqueues would lead to a memory leak.
+	 */
+	if (sk->sk_shutdown == SHUTDOWN_MASK) {
+		virtio_transport_reset_no_sock(t, skb);
+		return -ESHUTDOWN;
+	}
+
 	child = vsock_create_connected(sk);
 	if (!child) {
 		virtio_transport_reset_no_sock(t, skb);




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux