All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Garzarella <sgarzare@redhat.com>
To: Minh Nguyen <minhnguyen.080505@gmail.com>
Cc: Bryan Tan <bryan-bt.tan@broadcom.com>,
	 Vishnu Dasa <vishnu.dasa@broadcom.com>,
	"David S . Miller" <davem@davemloft.net>,
	 Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>,
	 Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
	 bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org,
	virtualization@lists.linux.dev,  linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH net v2] vsock/vmci: fix UAF when peer resets connection during handshake
Date: Tue, 12 May 2026 09:06:51 +0200	[thread overview]
Message-ID: <agLRfHBHJ2990NJo@sgarzare-redhat> (raw)
In-Reply-To: <20260512025851.189140-1-minhnguyen.080505@gmail.com>

On Tue, May 12, 2026 at 09:58:51AM +0700, Minh Nguyen wrote:
>vmci_transport_recv_connecting_server() jumps to its destroy: label
>and performs an unconditional sock_put(pending) to release the
>explicit sock_hold() taken by vmci_transport_recv_listen() before
>schedule_delayed_work().  The existing comment claimed this was safe
>because the listen handler removes pending from the pending list on
>the way out, which would prevent vsock_pending_work() from dropping
>the same reference later.
>
>That assumption breaks for a peer RST.  The default arm of the packet
>switch sets:
>
>	err = pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST ? 0 : -EINVAL;
>
>and vmci_transport_recv_listen() only calls vsock_remove_pending()
>when err < 0:
>
>	if (err < 0)
>		vsock_remove_pending(sk, pending);
>
>For RST (err == 0) the socket stays on the pending list, so when
>vsock_pending_work() fires it takes the is_pending=true path and
>drops all three references itself: the pending-list reference via
>vsock_remove_pending(), then the two trailing sock_put(sk) calls.
>The unconditional sock_put() in destroy: had already dropped the
>explicit sock_hold() reference, so the second trailing sock_put(sk)
>in vsock_pending_work() is a write into the freed AF_VSOCK slab
>object.  KASAN reports a slab-use-after-free write of 4 bytes from
>refcount_warn_saturate() on the workqueue path:
>
>  BUG: KASAN: slab-use-after-free in refcount_warn_saturate
>  Write of size 4 at addr ffff88800b1cac80 by task kworker
>  Workqueue: events vsock_pending_work
>  Call Trace:
>   refcount_warn_saturate
>   vsock_pending_work
>   process_one_work
>   worker_thread
>
>Triggering the bug requires only the ability to open a VSOCK
>connection to the target and send a RST before the listener accepts.
>
>Skip the sock_put() in destroy: when err == 0 so it only compensates
>the cases where vmci_transport_recv_listen() actually calls
>vsock_remove_pending().  RST is the only path that reaches destroy:
>with err == 0; every other path produces a negative value, so their
>behaviour is unchanged.
>
>Verified on lts-6.12.79 with KASAN enabled (CONFIG_KASAN_INLINE=y,
>kasan_multi_shot): same trigger binary, same VM, 100 iterations:
>without this patch 52 KASAN slab-use-after-free reports fire; with
>this patch applied, 0 reports.
>
>Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
>Cc: stable@vger.kernel.org
>Signed-off-by: Minh Nguyen <minhnguyen.080505@gmail.com>
>Assisted-by: Claude:claude-opus-4-7
>---
>v2:
>  - Resubmit to netdev per Stefano Garzarella's request after v1 review.
>  - Retested the PoC with the patch applied on lts-6.12.79 with KASAN
>    enabled: 52/100 unpatched -> 0/100 patched (same trigger binary,
>    same VM, 100 iterations); test summary captured in the commit
>    message.
>  - Changed Cc: stable@kernel.org -> stable@vger.kernel.org now that the
>    bug is no longer embargoed.
>  - Rebased onto net/main (no functional change to the diff).
>
>v1 was sent to security@kernel.org on 2026-05-10 (not on lore archives;
>no public link available).  v1 review summary, for reference:
>  - Stefano Garzarella (vsock maintainer): "Overall LGTM, but I'd wait
>    vmware guys on this that know this code better."  Asked for retest
>    and resubmission via the net tree workflow.
>  - Bryan Tan (VMCI maintainer): "Thanks for the fix, it looks good to
>    me."  Also noted that no modern VMware product allows guest-to-guest
>    VMCI communication, so the practical attack surface is host -> guest.
>
> net/vmw_vsock/vmci_transport.c | 16 +++++++++-------
> 1 file changed, 9 insertions(+), 7 deletions(-)

Acked-by: Stefano Garzarella <sgarzare@redhat.com>

>
>diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
>index 4296ca1..88d7128 100644
>--- a/net/vmw_vsock/vmci_transport.c
>+++ b/net/vmw_vsock/vmci_transport.c
>@@ -1269,14 +1269,16 @@ vmci_transport_recv_connecting_server(struct sock *listener,
> destroy:
> 	pending->sk_err = skerr;
> 	pending->sk_state = TCP_CLOSE;
>-	/* As long as we drop our reference, all necessary cleanup will handle
>-	 * when the cleanup function drops its reference and our destruct
>-	 * implementation is called.  Note that since the listen handler will
>-	 * remove pending from the pending list upon our failure, the cleanup
>-	 * function won't drop the additional reference, which is why we do it
>-	 * here.
>+	/* Drop the reference taken by vmci_transport_recv_listen() before
>+	 * schedule_delayed_work() only on real errors.  For a peer RST
>+	 * (err == 0) the listener leaves pending on the pending list, and
>+	 * vsock_pending_work() will drop that reference itself when it
>+	 * later cleans the socket up.  Calling sock_put() here in that
>+	 * case would be a double-put and free the socket while
>+	 * vsock_pending_work() still holds it.
> 	 */
>-	sock_put(pending);
>+	if (err < 0)
>+		sock_put(pending);
>
> 	return err;
> }
>
>base-commit: be48e5fe51a5864566307998286a699d6b986934
>-- 
>2.54.0
>


  reply	other threads:[~2026-05-12  7:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-12  2:58 [PATCH net v2] vsock/vmci: fix UAF when peer resets connection during handshake Minh Nguyen
2026-05-12  7:06 ` Stefano Garzarella [this message]
2026-05-12 13:12 ` Bryan Tan
2026-05-14 13:26 ` Paolo Abeni

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=agLRfHBHJ2990NJo@sgarzare-redhat \
    --to=sgarzare@redhat.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=bryan-bt.tan@broadcom.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=minhnguyen.080505@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=stable@vger.kernel.org \
    --cc=virtualization@lists.linux.dev \
    --cc=vishnu.dasa@broadcom.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.