* [PATCH net v3 0/2] vsock: validate packet sources after bound lookup fallback
@ 2026-08-23 17:58 Daehyeon Ko
2026-08-23 17:58 ` [PATCH net v3 1/2] vsock/virtio: validate packet source for connected sockets Daehyeon Ko
2026-08-23 17:58 ` [PATCH net v3 2/2] vsock/vmci: " Daehyeon Ko
0 siblings, 2 replies; 5+ messages in thread
From: Daehyeon Ko @ 2026-08-23 17:58 UTC (permalink / raw)
To: netdev
Cc: sgarzare, stefanha, bobbyeshleman, davem, edumazet, kuba, pabeni,
horms, mst, jasowangio, xuanzhuo, eperezma, bryan-bt.tan,
vishnu.dasa, bcm-kernel-feedback-list, virtualization, kvm,
linux-kernel
Both virtio and VMCI look up connected sockets by the full tuple before
falling back to a destination-only bound lookup. The fallback can select a
non-listening socket without validating the packet source.
V2 covered only the virtio path. Following Stefano's review, this series
moves the source and transport validation into a documented AF_VSOCK helper
and uses it for both virtio and VMCI. The VMCI patch checks both its
bottom-half and deferred workqueue receive paths.
The combined series was tested on x86_64 KASAN kernels. The original
cross-UID virtio injection remained blocked in three boots, CID_LOCAL and
CID_HOST loopback aliases passed, selected VSOCK selftests passed, and VMCI
accepted a matched RST while rejecting a mismatched-context RST in three
boots. All changed objects built without warnings under allmodconfig and
allyesconfig with W=1.
The current-tree guest-CID vhost probe could not be rerun because the test
user lacks access to /dev/vhost-vsock.
Changes in v3:
- Move transport and source validation into vsock_check_source().
- Trust the internally generated source CID for the local transport.
- Add VMCI validation in the bottom-half and workqueue receive paths.
- Send the related virtio and VMCI fixes in one series.
- Do not carry Bobby's v2 Reviewed-by because the helper and loopback logic
changed; renewed review is requested.
v2: https://lore.kernel.org/netdev/20260820001517.2148196-1-4ncienth@gmail.com/
v1: https://lore.kernel.org/netdev/20260813121236.2328599-1-4ncienth@gmail.com/
Daehyeon Ko (2):
vsock/virtio: validate packet source for connected sockets
vsock/vmci: validate packet source for connected sockets
include/net/af_vsock.h | 3 +++
net/vmw_vsock/af_vsock.c | 32 +++++++++++++++++++++++++
net/vmw_vsock/virtio_transport_common.c | 3 ++-
net/vmw_vsock/vmci_transport.c | 29 +++++++++++++++++-----
4 files changed, 60 insertions(+), 7 deletions(-)
base-commit: 7cbfb180945ce529608e4d4e24a6d483699fab1e
--
2.54.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v3 1/2] vsock/virtio: validate packet source for connected sockets
2026-08-23 17:58 [PATCH net v3 0/2] vsock: validate packet sources after bound lookup fallback Daehyeon Ko
@ 2026-08-23 17:58 ` Daehyeon Ko
2026-08-25 22:32 ` Bobby Eshleman
2026-08-23 17:58 ` [PATCH net v3 2/2] vsock/vmci: " Daehyeon Ko
1 sibling, 1 reply; 5+ messages in thread
From: Daehyeon Ko @ 2026-08-23 17:58 UTC (permalink / raw)
To: netdev
Cc: sgarzare, stefanha, bobbyeshleman, davem, edumazet, kuba, pabeni,
horms, mst, jasowangio, xuanzhuo, eperezma, bryan-bt.tan,
vishnu.dasa, bcm-kernel-feedback-list, virtualization, kvm,
linux-kernel
virtio_transport_recv_pkt() looks up sockets first by the full source and
destination tuple, then by destination only in the bound table. The
fallback is needed for listening and connecting sockets, but sockets remain
in the bound table after connect(), so it can also return a non-listening
socket.
The fallback does not validate the source address. In TCP_SYN_SENT, a
RESPONSE from an unrelated source can transition the victim socket to
TCP_ESTABLISHED while its stored remote address remains unchanged.
Subsequent RW packets from that source are delivered through the same
destination-only fallback.
This was reproduced with capability-empty processes under different UIDs.
The attacker discovered the target tuple through unprivileged AF_VSOCK
sock_diag and caused the victim socket to read 16 attacker-chosen bytes;
the intended peer-side socket read 0 of those 16 bytes.
Add vsock_check_source() to validate the transport, source port and source
CID against the peer stored in a non-listening socket. The local transport
is the CID exception because its packets are generated internally with
VMADDR_CID_LOCAL as their source, including connections using CID aliases.
Use the helper after lock_sock() in the virtio receive path.
Fixes: 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko")
Closes: https://lore.kernel.org/netdev/20260813121236.2328599-1-4ncienth@gmail.com/
Cc: stable@vger.kernel.org
Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
---
include/net/af_vsock.h | 3 +++
net/vmw_vsock/af_vsock.c | 32 +++++++++++++++++++++++++
net/vmw_vsock/virtio_transport_common.c | 3 ++-
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 3357ee62d..5549298c1 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -229,6 +229,9 @@ struct sock *vsock_find_bound_socket_net(struct sockaddr_vm *addr,
struct sock *vsock_find_connected_socket_net(struct sockaddr_vm *src,
struct sockaddr_vm *dst,
struct net *net);
+bool vsock_check_source(const struct vsock_sock *vsk,
+ const struct vsock_transport *transport,
+ const struct sockaddr_vm *src);
void vsock_remove_sock(struct vsock_sock *vsk);
void vsock_for_each_connected_socket(struct vsock_transport *transport,
void (*fn)(struct sock *sk));
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index a33b2a2d3..f840498b5 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -438,6 +438,38 @@ struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
}
EXPORT_SYMBOL_GPL(vsock_find_connected_socket);
+/**
+ * vsock_check_source - validate a packet source against a socket peer
+ * @vsk: socket receiving the packet
+ * @transport: transport receiving the packet
+ * @src: source address from the packet
+ *
+ * Return: true if the packet arrived on the socket's assigned transport and
+ * its source matches the stored peer. Loopback packets are generated
+ * internally and always use the local CID as their source, including
+ * connections using a valid CID alias.
+ *
+ * The caller must hold the socket lock and must not call this for listening
+ * sockets, which accept packets from any source and have no assigned
+ * transport.
+ */
+bool vsock_check_source(const struct vsock_sock *vsk,
+ const struct vsock_transport *transport,
+ const struct sockaddr_vm *src)
+{
+ if (vsk->transport != transport)
+ return false;
+
+ if (src->svm_port != vsk->remote_addr.svm_port)
+ return false;
+
+ if (src->svm_cid == vsk->remote_addr.svm_cid)
+ return true;
+
+ return transport->get_local_cid() == VMADDR_CID_LOCAL;
+}
+EXPORT_SYMBOL_GPL(vsock_check_source);
+
void vsock_remove_sock(struct vsock_sock *vsk)
{
/* Transport reassignment must not remove the binding. */
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index e4ebaa70f..6301c108a 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -1823,7 +1823,8 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
* lock_sock (note: listener sockets are not assigned to any transport)
*/
if (sock_flag(sk, SOCK_DONE) ||
- (sk->sk_state != TCP_LISTEN && vsk->transport != &t->transport)) {
+ (sk->sk_state != TCP_LISTEN &&
+ !vsock_check_source(vsk, &t->transport, &src))) {
(void)virtio_transport_reset_no_sock(t, skb, net);
release_sock(sk);
sock_put(sk);
--
2.54.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net v3 2/2] vsock/vmci: validate packet source for connected sockets
2026-08-23 17:58 [PATCH net v3 0/2] vsock: validate packet sources after bound lookup fallback Daehyeon Ko
2026-08-23 17:58 ` [PATCH net v3 1/2] vsock/virtio: validate packet source for connected sockets Daehyeon Ko
@ 2026-08-23 17:58 ` Daehyeon Ko
2026-08-25 9:19 ` Paolo Abeni
1 sibling, 1 reply; 5+ messages in thread
From: Daehyeon Ko @ 2026-08-23 17:58 UTC (permalink / raw)
To: netdev
Cc: sgarzare, stefanha, bobbyeshleman, davem, edumazet, kuba, pabeni,
horms, mst, jasowangio, xuanzhuo, eperezma, bryan-bt.tan,
vishnu.dasa, bcm-kernel-feedback-list, virtualization, kvm,
linux-kernel, Sashiko
vmci_transport_recv_stream_cb() looks up sockets first by the full source
and destination tuple, then by destination only in the bound table. The
fallback can select a non-listening socket without checking whether the
packet came from its stored peer.
This was reproduced with two VMCI contexts. A RST from the context not
stored in a TCP_SYN_SENT socket reset that socket after it was selected by
the destination-only lookup.
VMCI can process notification packets in bottom-half context when the
socket is not owned by user context, or defer packets to a workqueue. Use
vsock_check_source() after taking the socket lock in the bottom-half path,
and recheck after lock_sock() in the workqueue path. Listening sockets
continue to accept packets from any source.
Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/netdev/20260814121255.6B5001F000E9@smtp.kernel.org/
Cc: stable@vger.kernel.org
Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
---
net/vmw_vsock/vmci_transport.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 1c4ee039c..b612a9893 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -680,11 +680,13 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
struct vmci_transport_packet *pkt;
struct vsock_sock *vsk;
bool bh_process_pkt;
+ bool drop_pkt;
int err;
sk = NULL;
err = VMCI_SUCCESS;
bh_process_pkt = false;
+ drop_pkt = false;
/* Ignore incoming packets from resources that aren't vsock
* implementations.
@@ -765,17 +767,26 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
bh_lock_sock(sk);
if (!sock_owned_by_user(sk)) {
- /* The local context ID may be out of date, update it. */
- vsk->local_addr.svm_cid = dst.svm_cid;
+ if (sk->sk_state != TCP_LISTEN &&
+ !vsock_check_source(vsk, &vmci_transport, &src)) {
+ drop_pkt = true;
+ err = VMCI_ERROR_NO_ACCESS;
+ } else {
+ /* The local context ID may be out of date, update it. */
+ vsk->local_addr.svm_cid = dst.svm_cid;
- if (sk->sk_state == TCP_ESTABLISHED)
- vmci_trans(vsk)->notify_ops->handle_notify_pkt(
- sk, pkt, true, &dst, &src,
- &bh_process_pkt);
+ if (sk->sk_state == TCP_ESTABLISHED)
+ vmci_trans(vsk)->notify_ops->handle_notify_pkt(sk, pkt, true,
+ &dst, &src,
+ &bh_process_pkt);
+ }
}
bh_unlock_sock(sk);
+ if (drop_pkt)
+ goto out;
+
if (!bh_process_pkt) {
struct vmci_transport_recv_pkt_info *recv_pkt_info;
@@ -900,6 +911,7 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
{
struct vmci_transport_recv_pkt_info *recv_pkt_info;
struct vmci_transport_packet *pkt;
+ struct sockaddr_vm src;
struct sock *sk;
recv_pkt_info =
@@ -908,6 +920,10 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
pkt = &recv_pkt_info->pkt;
lock_sock(sk);
+ vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
+ if (sk->sk_state != TCP_LISTEN &&
+ !vsock_check_source(vsock_sk(sk), &vmci_transport, &src))
+ goto out;
/* The local context ID may be out of date. */
vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context;
@@ -937,6 +953,7 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
break;
}
+out:
release_sock(sk);
kfree(recv_pkt_info);
/* Release reference obtained in the stream callback when we fetched
--
2.54.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net v3 2/2] vsock/vmci: validate packet source for connected sockets
2026-08-23 17:58 ` [PATCH net v3 2/2] vsock/vmci: " Daehyeon Ko
@ 2026-08-25 9:19 ` Paolo Abeni
0 siblings, 0 replies; 5+ messages in thread
From: Paolo Abeni @ 2026-08-25 9:19 UTC (permalink / raw)
To: 4ncienth
Cc: netdev, sgarzare, stefanha, bobbyeshleman, davem, edumazet, kuba,
pabeni, horms, mst, jasowangio, xuanzhuo, eperezma, bryan-bt.tan,
vishnu.dasa, bcm-kernel-feedback-list, virtualization, kvm,
linux-kernel, sashiko-bot
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://netdev-ai.bots.linux.dev/sashiko/
---
vsock/vmci: validate packet source for connected sockets
This adds a vsock_check_source() test to the VMCI stream receive paths so
that a non-listening socket found by the destination-only bound-table
lookup no longer processes packets from a context other than its stored
peer. The check is applied both under bh_lock_sock() in
vmci_transport_recv_stream_cb() and after lock_sock() in
vmci_transport_recv_pkt_work().
Closes: https://lore.kernel.org/netdev/20260814121255.6B5001F000E9@smtp.kernel.org/
> diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
> index 1c4ee039c1662..b612a9893856a 100644
> --- a/net/vmw_vsock/vmci_transport.c
> +++ b/net/vmw_vsock/vmci_transport.c
[ ... ]
> @@ -765,17 +767,26 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
> bh_lock_sock(sk);
>
> if (!sock_owned_by_user(sk)) {
> - /* The local context ID may be out of date, update it. */
> - vsk->local_addr.svm_cid = dst.svm_cid;
> + if (sk->sk_state != TCP_LISTEN &&
> + !vsock_check_source(vsk, &vmci_transport, &src)) {
> + drop_pkt = true;
> + err = VMCI_ERROR_NO_ACCESS;
> + } else {
> + /* The local context ID may be out of date, update it. */
> + vsk->local_addr.svm_cid = dst.svm_cid;
>
> - if (sk->sk_state == TCP_ESTABLISHED)
> - vmci_trans(vsk)->notify_ops->handle_notify_pkt(
> - sk, pkt, true, &dst, &src,
> - &bh_process_pkt);
> + if (sk->sk_state == TCP_ESTABLISHED)
> + vmci_trans(vsk)->notify_ops->handle_notify_pkt(sk, pkt, true,
> + &dst, &src,
> + &bh_process_pkt);
> + }
> }
>
> bh_unlock_sock(sk);
>
> + if (drop_pkt)
> + goto out;
> +
[Severity: Medium]
Should these two new exits still emit an RST before dropping the packet?
Consider a stream socket that called bind() but never listen().
__vsock_bind_connectible() puts it in the bound table with sk_state
TCP_CLOSE, remote_addr left as {VMADDR_CID_ANY, VMADDR_PORT_ANY}, and
vsk->transport still NULL, because vsock_assign_transport() is only
called for connectible sockets from vsock_connect() (and at create time
for SOCK_DGRAM).
A REQUEST from a remote context to that port misses
vsock_find_connected_socket(), is matched by vsock_find_bound_socket(),
and then reaches the new check. vsock_check_source() fails on its very
first test:
net/vmw_vsock/af_vsock.c:vsock_check_source() {
if (vsk->transport != transport)
return false;
...
}
So drop_pkt is set and "goto out" skips the kmalloc/schedule_work()
handoff entirely. vmci_transport_send_reset_bh() is only reached on the
"no socket found" and allocation-failure paths, so nothing is sent back.
The same happens on the deferred path below, where the new "goto out"
jumps over the whole sk_state switch, including the default: arm whose
in-tree comment says the reset is required:
> @@ -908,6 +920,10 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
> pkt = &recv_pkt_info->pkt;
>
> lock_sock(sk);
> + vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
> + if (sk->sk_state != TCP_LISTEN &&
> + !vsock_check_source(vsock_sk(sk), &vmci_transport, &src))
> + goto out;
>
> /* The local context ID may be out of date. */
> vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context;
net/vmw_vsock/vmci_transport.c:vmci_transport_recv_pkt_work() {
...
default:
/* Because this function does not run in the same context as
* vmci_transport_recv_stream_cb it is possible that the
* socket has closed. We need to let the other side know or it
* could be sitting in a connect and hang forever. Send a
* reset to prevent that.
*/
vmci_transport_send_reset(sk, pkt);
break;
}
Before this change that arm did transmit an RST for exactly this case,
since vmci_transport_send_reset() handles an unbound remote_addr by
replying to the packet's own source:
net/vmw_vsock/vmci_transport.c:vmci_transport_send_reset() {
...
if (vsock_addr_bound(&vsk->remote_addr)) {
dst_ptr = &vsk->remote_addr;
} else {
vsock_addr_init(&dst, pkt->dg.src.context,
pkt->src_port);
dst_ptr = &dst;
}
...
}
With the reply gone, does the remote connect() now block for
vsk->connect_timeout and return -ETIMEDOUT instead of -ECONNRESET? The
same loss of the reply would apply to a socket disconnected via
connect(AF_UNSPEC), which resets remote_addr to {VMADDR_CID_ANY,
VMADDR_PORT_ANY}.
Returning VMCI_ERROR_NO_ACCESS from the datagram callback does not turn
into a protocol reply, so is there anything left that notifies the peer?
For comparison, the virtio side runs the same source test but resets the
sender before dropping:
net/vmw_vsock/virtio_transport_common.c:virtio_transport_recv_pkt() {
...
if (sock_flag(sk, SOCK_DONE) ||
(sk->sk_state != TCP_LISTEN &&
!vsock_check_source(vsk, &t->transport, &src))) {
(void)virtio_transport_reset_no_sock(t, skb, net);
...
}
Would it make sense to follow that convention here, and to mention the
new drop-without-reply semantics in the changelog?
--
This is an AI-generated review.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v3 1/2] vsock/virtio: validate packet source for connected sockets
2026-08-23 17:58 ` [PATCH net v3 1/2] vsock/virtio: validate packet source for connected sockets Daehyeon Ko
@ 2026-08-25 22:32 ` Bobby Eshleman
0 siblings, 0 replies; 5+ messages in thread
From: Bobby Eshleman @ 2026-08-25 22:32 UTC (permalink / raw)
To: Daehyeon Ko
Cc: netdev, sgarzare, stefanha, davem, edumazet, kuba, pabeni, horms,
mst, jasowangio, xuanzhuo, eperezma, bryan-bt.tan, vishnu.dasa,
bcm-kernel-feedback-list, virtualization, kvm, linux-kernel
On Mon, Aug 24, 2026 at 02:58:57AM +0900, Daehyeon Ko wrote:
> virtio_transport_recv_pkt() looks up sockets first by the full source and
> destination tuple, then by destination only in the bound table. The
> fallback is needed for listening and connecting sockets, but sockets remain
> in the bound table after connect(), so it can also return a non-listening
> socket.
>
> The fallback does not validate the source address. In TCP_SYN_SENT, a
> RESPONSE from an unrelated source can transition the victim socket to
> TCP_ESTABLISHED while its stored remote address remains unchanged.
> Subsequent RW packets from that source are delivered through the same
> destination-only fallback.
>
> This was reproduced with capability-empty processes under different UIDs.
> The attacker discovered the target tuple through unprivileged AF_VSOCK
> sock_diag and caused the victim socket to read 16 attacker-chosen bytes;
> the intended peer-side socket read 0 of those 16 bytes.
>
> Add vsock_check_source() to validate the transport, source port and source
> CID against the peer stored in a non-listening socket. The local transport
> is the CID exception because its packets are generated internally with
> VMADDR_CID_LOCAL as their source, including connections using CID aliases.
>
> Use the helper after lock_sock() in the virtio receive path.
>
> Fixes: 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko")
> Closes: https://lore.kernel.org/netdev/20260813121236.2328599-1-4ncienth@gmail.com/
> Cc: stable@vger.kernel.org
> Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
> Assisted-by: Codex:gpt-5.6-sol
> Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
> ---
> include/net/af_vsock.h | 3 +++
> net/vmw_vsock/af_vsock.c | 32 +++++++++++++++++++++++++
> net/vmw_vsock/virtio_transport_common.c | 3 ++-
> 3 files changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
> index 3357ee62d..5549298c1 100644
> --- a/include/net/af_vsock.h
> +++ b/include/net/af_vsock.h
> @@ -229,6 +229,9 @@ struct sock *vsock_find_bound_socket_net(struct sockaddr_vm *addr,
> struct sock *vsock_find_connected_socket_net(struct sockaddr_vm *src,
> struct sockaddr_vm *dst,
> struct net *net);
> +bool vsock_check_source(const struct vsock_sock *vsk,
> + const struct vsock_transport *transport,
> + const struct sockaddr_vm *src);
> void vsock_remove_sock(struct vsock_sock *vsk);
> void vsock_for_each_connected_socket(struct vsock_transport *transport,
> void (*fn)(struct sock *sk));
> diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> index a33b2a2d3..f840498b5 100644
> --- a/net/vmw_vsock/af_vsock.c
> +++ b/net/vmw_vsock/af_vsock.c
> @@ -438,6 +438,38 @@ struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
> }
> EXPORT_SYMBOL_GPL(vsock_find_connected_socket);
>
> +/**
> + * vsock_check_source - validate a packet source against a socket peer
> + * @vsk: socket receiving the packet
> + * @transport: transport receiving the packet
> + * @src: source address from the packet
> + *
> + * Return: true if the packet arrived on the socket's assigned transport and
> + * its source matches the stored peer. Loopback packets are generated
> + * internally and always use the local CID as their source, including
> + * connections using a valid CID alias.
> + *
> + * The caller must hold the socket lock and must not call this for listening
> + * sockets, which accept packets from any source and have no assigned
> + * transport.
> + */
> +bool vsock_check_source(const struct vsock_sock *vsk,
> + const struct vsock_transport *transport,
> + const struct sockaddr_vm *src)
> +{
> + if (vsk->transport != transport)
> + return false;
> +
> + if (src->svm_port != vsk->remote_addr.svm_port)
> + return false;
> +
> + if (src->svm_cid == vsk->remote_addr.svm_cid)
> + return true;
> +
> + return transport->get_local_cid() == VMADDR_CID_LOCAL;
> +}
> +EXPORT_SYMBOL_GPL(vsock_check_source);
> +
> void vsock_remove_sock(struct vsock_sock *vsk)
> {
> /* Transport reassignment must not remove the binding. */
> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> index e4ebaa70f..6301c108a 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -1823,7 +1823,8 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
> * lock_sock (note: listener sockets are not assigned to any transport)
> */
> if (sock_flag(sk, SOCK_DONE) ||
> - (sk->sk_state != TCP_LISTEN && vsk->transport != &t->transport)) {
> + (sk->sk_state != TCP_LISTEN &&
> + !vsock_check_source(vsk, &t->transport, &src))) {
> (void)virtio_transport_reset_no_sock(t, skb, net);
> release_sock(sk);
> sock_put(sk);
> --
> 2.54.0
>
Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-25 22:32 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-23 17:58 [PATCH net v3 0/2] vsock: validate packet sources after bound lookup fallback Daehyeon Ko
2026-08-23 17:58 ` [PATCH net v3 1/2] vsock/virtio: validate packet source for connected sockets Daehyeon Ko
2026-08-25 22:32 ` Bobby Eshleman
2026-08-23 17:58 ` [PATCH net v3 2/2] vsock/vmci: " Daehyeon Ko
2026-08-25 9:19 ` Paolo Abeni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox