lkml.org 
[lkml]   [2018]   [Dec]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.9 30/34] vhost/vsock: fix reset orphans race with close timeout
    Date
    From: Stefan Hajnoczi <stefanha@redhat.com>

    [ Upstream commit c38f57da428b033f2721b611d84b1f40bde674a8 ]

    If a local process has closed a connected socket and hasn't received a
    RST packet yet, then the socket remains in the table until a timeout
    expires.

    When a vhost_vsock instance is released with the timeout still pending,
    the socket is never freed because vhost_vsock has already set the
    SOCK_DONE flag.

    Check if the close timer is pending and let it close the socket. This
    prevents the race which can leak sockets.

    Reported-by: Maximilian Riemensberger <riemensberger@cadami.net>
    Cc: Graham Whaley <graham.whaley@gmail.com>
    Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/vhost/vsock.c | 22 +++++++++++++++-------
    1 file changed, 15 insertions(+), 7 deletions(-)

    diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
    index 0ec970ca64ce..5d77a7491edb 100644
    --- a/drivers/vhost/vsock.c
    +++ b/drivers/vhost/vsock.c
    @@ -551,13 +551,21 @@ static void vhost_vsock_reset_orphans(struct sock *sk)
    * executing.
    */

    - if (!vhost_vsock_get(vsk->remote_addr.svm_cid)) {
    - sock_set_flag(sk, SOCK_DONE);
    - vsk->peer_shutdown = SHUTDOWN_MASK;
    - sk->sk_state = SS_UNCONNECTED;
    - sk->sk_err = ECONNRESET;
    - sk->sk_error_report(sk);
    - }
    + /* If the peer is still valid, no need to reset connection */
    + if (vhost_vsock_get(vsk->remote_addr.svm_cid))
    + return;
    +
    + /* If the close timeout is pending, let it expire. This avoids races
    + * with the timeout callback.
    + */
    + if (vsk->close_work_scheduled)
    + return;
    +
    + sock_set_flag(sk, SOCK_DONE);
    + vsk->peer_shutdown = SHUTDOWN_MASK;
    + sk->sk_state = SS_UNCONNECTED;
    + sk->sk_err = ECONNRESET;
    + sk->sk_error_report(sk);
    }

    static int vhost_vsock_dev_release(struct inode *inode, struct file *file)
    --
    2.19.1
    \
     
     \ /
      Last update: 2018-12-13 05:39    [W:4.283 / U:0.472 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site