From: netdev-bot+sashiko@kernel.org
To: bartlomiej.dmitruk@isec.pl
Cc: decui@microsoft.com, wei.liu@kernel.org, haiyangz@microsoft.com,
kys@microsoft.com, linux-hyperv@vger.kernel.org,
netdev@vger.kernel.org, sgarzare@redhat.com, mst@redhat.com,
kuba@kernel.org
Subject: Re: [PATCH] vsock/hv_sock: fix socket/table leak when rescind races the delayed close
Date: Mon, 21 Sep 2026 23:23:56 +0000 [thread overview]
Message-ID: <179003303663.2160803.2038691427232135222@kernel.org> (raw)
In-Reply-To: <20260917220213.56102-1-bartlomiej.dmitruk@isec.pl>
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 0 (1) · Medium: 1 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] Missing `Fixes:` tag and stable Cc on a real bug fix.
Pre-existing issues:
- [High] The identical leak the patch closes for hv_sock remains in the
sibling transport that shares the same `vsk->close_work` /…
--
vsock/hv_sock: fix socket/table leak when rescind races the delayed close
This changes hvs_close_timeout() so that, when SOCK_DONE is already set but
vsk->close_work_scheduled is still true, the running work drops the
scheduling reference and calls vsock_remove_sock() itself. That covers the
case where hvs_close_connection() could not cancel the already-dequeued
work.
A couple of questions below.
> Make the running timeout complete the cleanup the rescind path could not:
> when SOCK_DONE is set but the work is still marked scheduled, drop the
> scheduling reference and remove the socket. The two cleanup sites are
> mutually exclusive and guarded by close_work_scheduled, so the reference
> is dropped exactly once. (cancel_delayed_work_sync() cannot be used from
> hvs_do_close_lock_held(): it runs under the same lock_sock() the work
> takes.)
>
> Signed-off-by: Bartłomiej Dmitruk <bartlomiej.dmitruk@isec.pl>
[Severity: Medium]
Should this carry a Fixes: tag and a stable Cc?
git blame on the pre-image points both halves of the defective logic at
commit a9eeb998c28d ("hv_sock: Add support for delayed close"): the
cancel_delayed_work()-conditional reference drop in
hvs_do_close_lock_held(), and the unconditional
vsk->close_work_scheduled = false in hvs_close_timeout().
The triggering event is a host-initiated channel rescind, so it is not
under guest control. Would the following trailers be appropriate, along
with a [PATCH net] subject prefix?
Fixes: a9eeb998c28d ("hv_sock: Add support for delayed close")
Cc: stable@vger.kernel.org
> diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
> index 855b15971c359..2779961fc18ca 100644
> --- a/net/vmw_vsock/hyperv_transport.c
> +++ b/net/vmw_vsock/hyperv_transport.c
> @@ -499,10 +499,18 @@ static void hvs_close_timeout(struct work_struct *work)
>
> sock_hold(sk);
> lock_sock(sk);
> - if (!sock_flag(sk, SOCK_DONE))
> + if (!sock_flag(sk, SOCK_DONE)) {
> hvs_do_close_lock_held(vsk, false);
> -
> - vsk->close_work_scheduled = false;
> + } else if (vsk->close_work_scheduled) {
> + /* A concurrent rescind (hvs_close_connection) set SOCK_DONE but
> + * could not cancel this already-running work, so it left the
> + * scheduling reference and vsock_remove_sock() to us. Finish
> + * the cleanup to avoid leaking the socket and its table entry.
> + */
> + vsk->close_work_scheduled = false;
> + vsock_remove_sock(vsk);
> + sock_put(sk);
> + }
> release_sock(sk);
> sock_put(sk);
> }
[Severity: High]
This is a pre-existing issue and not introduced by this patch, but does the
same struct sock leak still exist in virtio_transport_common.c, which uses
the same vsk->close_work and vsk->close_work_scheduled fields from
include/net/af_vsock.h?
virtio_transport_close_timeout() still has the pattern this hunk replaces:
net/vmw_vsock/virtio_transport_common.c:virtio_transport_close_timeout() {
sock_hold(sk);
lock_sock(sk);
if (!sock_flag(sk, SOCK_DONE)) {
(void)virtio_transport_reset(vsk, NULL);
virtio_transport_do_close(vsk, false);
}
vsk->close_work_scheduled = false;
release_sock(sk);
sock_put(sk);
}
and the cancel-failure path is the same one described in the changelog:
net/vmw_vsock/virtio_transport_common.c:virtio_transport_cancel_close_work() {
if (vsk->close_work_scheduled &&
(!cancel_timeout || cancel_delayed_work(&vsk->close_work))) {
vsk->close_work_scheduled = false;
virtio_transport_remove_sock(vsk);
/* Release refcnt obtained when we scheduled the timeout */
sock_put(sk);
}
}
The racing event there is a peer packet rather than a host rescind:
virtio_transport_recv_pkt()
lock_sock()
virtio_transport_recv_connected() /* VIRTIO_VSOCK_OP_RST */
virtio_transport_do_close(vsk, true)
virtio_transport_cancel_close_work(vsk, true)
If virtio_transport_close_timeout() has already been dequeued and is
blocked on lock_sock(), cancel_delayed_work() returns false, so
close_work_scheduled stays true, the scheduling sock_put() is skipped and
virtio_transport_remove_sock() is not called, while SOCK_DONE is set. The
work then resumes, skips the !sock_flag(sk, SOCK_DONE) branch, clears
close_work_scheduled and drops only its own local reference.
Does that leak the struct sock and its struct virtio_vsock_sock, leave the
socket in the bound/connected tables, and leave vvs->rx_queue unpurged? The
recovery in virtio_transport_destruct() -> virtio_transport_cancel_close_
work(vsk, true) would not run because sk_refcnt never reaches zero, and
would be a no-op anyway once the flag has been cleared.
Since both transports share close_work and close_work_scheduled, would it
make sense to put this cleanup rule in code common to both rather than only
in hyperv_transport.c, so the two users do not implement different
ownership protocols for the same field?
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260917220213.56102-1-bartlomiej.dmitruk%40isec.pl
prev parent reply other threads:[~2026-09-21 23:23 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-17 22:02 [PATCH] vsock/hv_sock: fix socket/table leak when rescind races the delayed close Bartłomiej Dmitruk
2026-09-18 2:56 ` Ivy Lopez
2026-09-18 12:47 ` Stefano Garzarella
2026-09-21 23:23 ` netdev-bot+sashiko [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=179003303663.2160803.2038691427232135222@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=bartlomiej.dmitruk@isec.pl \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kuba@kernel.org \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=sgarzare@redhat.com \
--cc=wei.liu@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox