* FAILED: patch "[PATCH] vhost/vsock: size receive SKBs from declared payload" failed to apply to 6.1-stable tree
@ 2026-11-10 1:19 Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 1/3] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put() Sasha Levin
0 siblings, 1 reply; 4+ messages in thread
From: Sasha Levin @ 2026-11-10 1:19 UTC (permalink / raw)
To: 4ncienth, sgarzare, mst, pabeni; +Cc: stable
The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x d5e912448cd98b261eba8e35ab838f2dc69a79f5
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '20261109201916-failed-6.1-d5e912448cd9@kernel.org' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Thanks,
Sasha
------------------ original commit in Linus's tree ------------------
From d5e912448cd98b261eba8e35ab838f2dc69a79f5 Mon Sep 17 00:00:00 2001
From: Daehyeon Ko <4ncienth@gmail.com>
Date: Mon, 5 Oct 2026 08:51:01 +0900
Subject: [PATCH] vhost/vsock: size receive SKBs from declared payload
vhost_vsock_alloc_skb() sizes the skb from iov_length(), the total guest
descriptor length. virtio_transport_inc_rx_pkt() instead adds hdr->len to
rx_bytes and buf_used, and budgets each queued skb as SKB_TRUESIZE(0). The
guest controls the descriptor length and hdr->len independently.
A guest can therefore provide a 64 KiB descriptor while declaring a zero
payload. The descriptor-sized skb remains queued, rx_bytes and buf_used
remain unchanged, and only the fixed queue-entry budget limits retention.
This is not a lifetime leak: the skb is freed when dequeued or at socket
teardown. Repeating this across connections can nevertheless exhaust host
memory. On Linux v7.2, 455 such descriptors retained 30,255,680 bytes for
a 262,144-byte receive buffer; a full-payload control retained 265,984
bytes.
Vhost previously read hdr->len and allocated pkt->buf from that value. The
conversion from virtio_vsock_pkt to sk_buff instead allocated receive skbs
from the descriptor length, introducing the allocation-accounting mismatch.
Copy the header into a stack object and validate hdr->len before allocating
the skb. Size the allocation as sizeof(hdr) + payload_len so descriptor
capacity no longer determines queued memory. Check payload_len against
len - sizeof(hdr) to avoid addition overflow on 32-bit hosts.
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20261004235101.1464007-1-4ncienth@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/vhost/vsock.c | 34 ++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 0cb87971d7491..88a310390eb0a 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -360,7 +360,7 @@ static struct sk_buff *
vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
unsigned int out, unsigned int in)
{
- struct virtio_vsock_hdr *hdr;
+ struct virtio_vsock_hdr hdr;
struct iov_iter iov_iter;
struct sk_buff *skb;
size_t payload_len;
@@ -378,34 +378,32 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
return NULL;
- /* len contains both payload and hdr */
- skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
- if (!skb)
- return NULL;
-
iov_iter_init(&iov_iter, ITER_SOURCE, vq->iov, out, len);
- hdr = virtio_vsock_hdr(skb);
- nbytes = copy_from_iter(hdr, sizeof(*hdr), &iov_iter);
- if (nbytes != sizeof(*hdr)) {
+ nbytes = copy_from_iter(&hdr, sizeof(hdr), &iov_iter);
+ if (nbytes != sizeof(hdr)) {
vq_err(vq, "Expected %zu bytes for pkt->hdr, got %zu bytes\n",
- sizeof(*hdr), nbytes);
- kfree_skb(skb);
+ sizeof(hdr), nbytes);
return NULL;
}
- payload_len = le32_to_cpu(hdr->len);
+ payload_len = le32_to_cpu(hdr.len);
+
+ /* The pkt is too big or the length in the header is invalid */
+ if (payload_len > len - sizeof(hdr))
+ return NULL;
+
+ /* Allocate only for the payload declared in the header. */
+ skb = virtio_vsock_alloc_skb(payload_len + sizeof(hdr), GFP_KERNEL);
+ if (!skb)
+ return NULL;
+
+ memcpy(virtio_vsock_hdr(skb), &hdr, sizeof(hdr));
/* No payload */
if (!payload_len)
return skb;
- /* The pkt is too big or the length in the header is invalid */
- if (payload_len + sizeof(*hdr) > len) {
- kfree_skb(skb);
- return NULL;
- }
-
virtio_vsock_skb_put(skb, payload_len);
if (skb_copy_datagram_from_iter(skb, 0, &iov_iter, payload_len)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 6.1.y 1/3] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put()
2026-11-10 1:19 FAILED: patch "[PATCH] vhost/vsock: size receive SKBs from declared payload" failed to apply to 6.1-stable tree Sasha Levin
@ 2026-11-15 0:30 ` Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 2/3] vsock/virtio: Rename virtio_vsock_skb_rx_put() Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 3/3] vhost/vsock: size receive SKBs from declared payload Sasha Levin
0 siblings, 2 replies; 4+ messages in thread
From: Sasha Levin @ 2026-11-15 0:30 UTC (permalink / raw)
To: stable; +Cc: Will Deacon, Stefano Garzarella, Michael S. Tsirkin, Sasha Levin
From: Will Deacon <will@kernel.org>
[ Upstream commit 87dbae5e36613a6020f3d64a2eaeac0a1e0e6dc6 ]
virtio_vsock_skb_rx_put() only calls skb_put() if the length in the
packet header is not zero even though skb_put() handles this case
gracefully.
Remove the functionally redundant check from virtio_vsock_skb_rx_put()
and, on the assumption that this is a worthwhile optimisation for
handling credit messages, augment the existing length checks in
virtio_transport_rx_work() to elide the call for zero-length payloads.
Since the callers all have the length, extend virtio_vsock_skb_rx_put()
to take it as an additional parameter rather than fish it back out of
the packet header.
Note that the vhost code already has similar logic in
vhost_vsock_alloc_skb().
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
Message-Id: <20250717090116.11987-4-will@kernel.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Stable-dep-of: d5e912448cd9 ("vhost/vsock: size receive SKBs from declared payload")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vsock.c | 2 +-
include/linux/virtio_vsock.h | 9 ++-------
net/vmw_vsock/virtio_transport.c | 4 +++-
3 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 48002df5ef736..c08eb6774c427 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -372,7 +372,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
return NULL;
}
- virtio_vsock_skb_rx_put(skb);
+ virtio_vsock_skb_rx_put(skb, payload_len);
nbytes = copy_from_iter(skb->data, payload_len, &iov_iter);
if (nbytes != payload_len) {
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 689e9fc50e1b8..3b97af88edbca 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -46,14 +46,9 @@ static inline void virtio_vsock_skb_clear_tap_delivered(struct sk_buff *skb)
VIRTIO_VSOCK_SKB_CB(skb)->tap_delivered = false;
}
-static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb)
+static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb, u32 len)
{
- u32 len;
-
- len = le32_to_cpu(virtio_vsock_hdr(skb)->len);
-
- if (len > 0)
- skb_put(skb, len);
+ skb_put(skb, len);
}
static inline struct sk_buff *virtio_vsock_alloc_skb(unsigned int size, gfp_t mask)
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index 2f3e89cd4ebc2..feda96522b4f6 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -527,7 +527,9 @@ static void virtio_transport_rx_work(struct work_struct *work)
continue;
}
- virtio_vsock_skb_rx_put(skb);
+ if (payload_len)
+ virtio_vsock_skb_rx_put(skb, payload_len);
+
virtio_transport_deliver_tap_pkt(skb);
virtio_transport_recv_pkt(&virtio_transport, skb);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 6.1.y 2/3] vsock/virtio: Rename virtio_vsock_skb_rx_put()
2026-11-15 0:30 ` [PATCH 6.1.y 1/3] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put() Sasha Levin
@ 2026-11-15 0:30 ` Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 3/3] vhost/vsock: size receive SKBs from declared payload Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-11-15 0:30 UTC (permalink / raw)
To: stable; +Cc: Will Deacon, Stefano Garzarella, Michael S. Tsirkin, Sasha Levin
From: Will Deacon <will@kernel.org>
[ Upstream commit 8ca76151d2c8219edea82f1925a2a25907ff6a9d ]
In preparation for using virtio_vsock_skb_rx_put() when populating SKBs
on the vsock TX path, rename virtio_vsock_skb_rx_put() to
virtio_vsock_skb_put().
No functional change.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
Message-Id: <20250717090116.11987-9-will@kernel.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Stable-dep-of: d5e912448cd9 ("vhost/vsock: size receive SKBs from declared payload")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vsock.c | 2 +-
include/linux/virtio_vsock.h | 2 +-
net/vmw_vsock/virtio_transport.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index c08eb6774c427..1fc03038e5543 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -372,7 +372,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
return NULL;
}
- virtio_vsock_skb_rx_put(skb, payload_len);
+ virtio_vsock_skb_put(skb, payload_len);
nbytes = copy_from_iter(skb->data, payload_len, &iov_iter);
if (nbytes != payload_len) {
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 3b97af88edbca..f62ec310059b2 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -46,7 +46,7 @@ static inline void virtio_vsock_skb_clear_tap_delivered(struct sk_buff *skb)
VIRTIO_VSOCK_SKB_CB(skb)->tap_delivered = false;
}
-static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb, u32 len)
+static inline void virtio_vsock_skb_put(struct sk_buff *skb, u32 len)
{
skb_put(skb, len);
}
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index feda96522b4f6..b4b09d0b04325 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -528,7 +528,7 @@ static void virtio_transport_rx_work(struct work_struct *work)
}
if (payload_len)
- virtio_vsock_skb_rx_put(skb, payload_len);
+ virtio_vsock_skb_put(skb, payload_len);
virtio_transport_deliver_tap_pkt(skb);
virtio_transport_recv_pkt(&virtio_transport, skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 6.1.y 3/3] vhost/vsock: size receive SKBs from declared payload
2026-11-15 0:30 ` [PATCH 6.1.y 1/3] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put() Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 2/3] vsock/virtio: Rename virtio_vsock_skb_rx_put() Sasha Levin
@ 2026-11-15 0:30 ` Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-11-15 0:30 UTC (permalink / raw)
To: stable
Cc: Daehyeon Ko, Stefano Garzarella, Michael S. Tsirkin, Paolo Abeni,
Sasha Levin
From: Daehyeon Ko <4ncienth@gmail.com>
[ Upstream commit d5e912448cd98b261eba8e35ab838f2dc69a79f5 ]
vhost_vsock_alloc_skb() sizes the skb from iov_length(), the total guest
descriptor length. virtio_transport_inc_rx_pkt() instead adds hdr->len to
rx_bytes and buf_used, and budgets each queued skb as SKB_TRUESIZE(0). The
guest controls the descriptor length and hdr->len independently.
A guest can therefore provide a 64 KiB descriptor while declaring a zero
payload. The descriptor-sized skb remains queued, rx_bytes and buf_used
remain unchanged, and only the fixed queue-entry budget limits retention.
This is not a lifetime leak: the skb is freed when dequeued or at socket
teardown. Repeating this across connections can nevertheless exhaust host
memory. On Linux v7.2, 455 such descriptors retained 30,255,680 bytes for
a 262,144-byte receive buffer; a full-payload control retained 265,984
bytes.
Vhost previously read hdr->len and allocated pkt->buf from that value. The
conversion from virtio_vsock_pkt to sk_buff instead allocated receive skbs
from the descriptor length, introducing the allocation-accounting mismatch.
Copy the header into a stack object and validate hdr->len before allocating
the skb. Size the allocation as sizeof(hdr) + payload_len so descriptor
capacity no longer determines queued memory. Check payload_len against
len - sizeof(hdr) to avoid addition overflow on 32-bit hosts.
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20261004235101.1464007-1-4ncienth@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vsock.c | 34 ++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 1fc03038e5543..43533ae6ce211 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -327,7 +327,7 @@ static struct sk_buff *
vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
unsigned int out, unsigned int in)
{
- struct virtio_vsock_hdr *hdr;
+ struct virtio_vsock_hdr hdr;
struct iov_iter iov_iter;
struct sk_buff *skb;
size_t payload_len;
@@ -344,34 +344,32 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
if (len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
return NULL;
- /* len contains both payload and hdr */
- skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
- if (!skb)
- return NULL;
-
iov_iter_init(&iov_iter, ITER_SOURCE, vq->iov, out, len);
- hdr = virtio_vsock_hdr(skb);
- nbytes = copy_from_iter(hdr, sizeof(*hdr), &iov_iter);
- if (nbytes != sizeof(*hdr)) {
+ nbytes = copy_from_iter(&hdr, sizeof(hdr), &iov_iter);
+ if (nbytes != sizeof(hdr)) {
vq_err(vq, "Expected %zu bytes for pkt->hdr, got %zu bytes\n",
- sizeof(*hdr), nbytes);
- kfree_skb(skb);
+ sizeof(hdr), nbytes);
return NULL;
}
- payload_len = le32_to_cpu(hdr->len);
+ payload_len = le32_to_cpu(hdr.len);
+
+ /* The pkt is too big or the length in the header is invalid */
+ if (payload_len > len - sizeof(hdr))
+ return NULL;
+
+ /* Allocate only for the payload declared in the header. */
+ skb = virtio_vsock_alloc_skb(payload_len + sizeof(hdr), GFP_KERNEL);
+ if (!skb)
+ return NULL;
+
+ memcpy(virtio_vsock_hdr(skb), &hdr, sizeof(hdr));
/* No payload */
if (!payload_len)
return skb;
- /* The pkt is too big or the length in the header is invalid */
- if (payload_len + sizeof(*hdr) > len) {
- kfree_skb(skb);
- return NULL;
- }
-
virtio_vsock_skb_put(skb, payload_len);
nbytes = copy_from_iter(skb->data, payload_len, &iov_iter);
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-15 0:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-10 1:19 FAILED: patch "[PATCH] vhost/vsock: size receive SKBs from declared payload" failed to apply to 6.1-stable tree Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 1/3] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put() Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 2/3] vsock/virtio: Rename virtio_vsock_skb_rx_put() Sasha Levin
2026-11-15 0:30 ` [PATCH 6.1.y 3/3] vhost/vsock: size receive SKBs from declared payload Sasha Levin
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.