• Peilin Ye's avatar
    vsock: Fix memory leak in vsock_connect() · 7e97cfed
    Peilin Ye authored
    An O_NONBLOCK vsock_connect() request may try to reschedule
    @connect_work.  Imagine the following sequence of vsock_connect()
    requests:
    
      1. The 1st, non-blocking request schedules @connect_work, which will
         expire after 200 jiffies.  Socket state is now SS_CONNECTING;
    
      2. Later, the 2nd, blocking request gets interrupted by a signal after
         a few jiffies while waiting for the connection to be established.
         Socket state is back to SS_UNCONNECTED, but @connect_work is still
         pending, and will expire after 100 jiffies.
    
      3. Now, the 3rd, non-blocking request tries to schedule @connect_work
         again.  Since @connect_work is already scheduled,
         schedule_delayed_work() silently returns.  sock_hold() is called
         twice, but sock_put() will only be called once in
         vsock_connect_timeout(), causing a memory leak reported by syzbot:
    
      BUG: memory leak
      unreferenced object 0xffff88810ea56a40 (size 1232):
        comm "syz-executor756", pid 3604, jiffies 4294947681 (age 12.350s)
        hex dump (first 32 bytes):
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
          28 00 07 40 00 00 00 00 00 00 00 00 00 00 00 00  (..@............
        backtrace:
          [<ffffffff837c830e>] sk_prot_alloc+0x3e/0x1b0 net/core/sock.c:1930
          [<ffffffff837cbe22>] sk_alloc+0x32/0x2e0 net/core/sock.c:1989
          [<ffffffff842ccf68>] __vsock_create.constprop.0+0x38/0x320 net/vmw_vsock/af_vsock.c:734
          [<ffffffff842ce8f1>] vsock_create+0xc1/0x2d0 net/vmw_vsock/af_vsock.c:2203
          [<ffffffff837c0cbb>] __sock_create+0x1ab/0x2b0 net/socket.c:1468
          [<ffffffff837c3acf>] sock_create net/socket.c:1519 [inline]
          [<ffffffff837c3acf>] __sys_socket+0x6f/0x140 net/socket.c:1561
          [<ffffffff837c3bba>] __do_sys_socket net/socket.c:1570 [inline]
          [<ffffffff837c3bba>] __se_sys_socket net/socket.c:1568 [inline]
          [<ffffffff837c3bba>] __x64_sys_socket+0x1a/0x20 net/socket.c:1568
          [<ffffffff84512815>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
          [<ffffffff84512815>] do_syscall_64+0x35/0x80 arch/x86/entry/common.c:80
          [<ffffffff84600068>] entry_SYSCALL_64_after_hwframe+0x44/0xae
      <...>
    
    Use mod_delayed_work() instead: if @connect_work is already scheduled,
    reschedule it, and undo sock_hold() to keep the reference count
    balanced.
    
    Reported-and-tested-by: syzbot+b03f55bf128f9a38f064@syzkaller.appspotmail.com
    Fixes: d021c344 ("VSOCK: Introduce VM Sockets")
    Co-developed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
    Signed-off-by: default avatarStefano Garzarella <sgarzare@redhat.com>
    Reviewed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
    Signed-off-by: default avatarPeilin Ye <peilin.ye@bytedance.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    7e97cfed
af_vsock.c 58.2 KB