While reviewing the patch posted by Yiqi Sun [1] to fix an issue in
virtio_transport_build_skb(), I discovered another issue related to
the offset and length of the payload to be copied in the new skb.
This was introduced when we did the skb conversion, and fixed by
patch 1.
Patch 2 fixes the issue found by Yiqi Sun in a different way: using
iov_iter_kvec() to properly initialize all the iov_iter fields and
removing the linear vs non-linear split like we alredy do in
vhost-vsock.
It could have been a single patch, but since there were two affected
commits, I decided to keep the fixes separate.
[1] https://lore.kernel.org/netdev/20260430071110.380509-1-sunyiqixm@gmail.com/
Stefano Garzarella (2):
vsock/virtio: fix length and offset in tap skb for split packets
vsock/virtio: fix empty payload in tap skb for non-linear buffers
net/vmw_vsock/virtio_transport_common.c | 47 +++++++++----------------
1 file changed, 16 insertions(+), 31 deletions(-)
--
2.54.0
From: Stefano Garzarella <sgarzare@redhat.com>
virtio_transport_build_skb() builds a new skb to be delivered to the
vsockmon tap device. To build the new skb, it uses the original skb
data length as payload length, but as the comment notes, the original
packet stored in the skb may have been split in multiple packets, so we
need to use the length in the header, which is correctly updated before
the packet is delivered to the tap, and the offset for the data.
This was also similar to what we did before commit 71dc9ec9ac7d
("virtio/vsock: replace virtio_vsock_pkt with sk_buff") where we probably
missed something during the skb conversion.
Also update the comment above, which was left stale by the skb
conversion and still mentioned a buffer pointer that no longer exists.
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
net/vmw_vsock/virtio_transport_common.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
@@ -166,12 +166,12 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)structsk_buff*skb;size_tpayload_len;-/* A packet could be split to fit the RX buffer, so we can retrieve-*thepayloadlengthfromtheheaderandthebufferpointertaking-*careoftheoffsetintheoriginalpacket.+/* A packet could be split to fit the RX buffer, so we use+*thepayloadlengthfromtheheader,whichhasbeenupdated+*bythesendertoreflectthefragmentsize.*/pkt_hdr=virtio_vsock_hdr(pkt);-payload_len=pkt->len;+payload_len=le32_to_cpu(pkt_hdr->len);skb=alloc_skb(sizeof(*hdr)+sizeof(*pkt_hdr)+payload_len,GFP_ATOMIC);
From: Stefano Garzarella <sgarzare@redhat.com>
For non-linear skbs, virtio_transport_build_skb() goes through
virtio_transport_copy_nonlinear_skb() to copy the original payload
in the new skb to be delivered to the vsockmon tap device.
This manually initializes an iov_iter but does not set iov_iter.count.
Since the iov_iter is zero-initialized, the copy length is zero and no
payload is actually copied to the monitor interface, leaving data
un-initialized.
Fix this by removing the linear vs non-linear split and using
skb_copy_datagram_iter() with iov_iter_kvec() for all cases, as
vhost-vsock already does. This handles both linear and non-linear skbs,
properly initializes the iov_iter, and removes the now unused
virtio_transport_copy_nonlinear_skb().
While touching this code, let's also check the return value of
skb_copy_datagram_iter(), even though it's unlikely to fail.
Fixes: 4b0bf10eb077 ("vsock/virtio: non-linear skb handling for tap")
Reported-by: Yiqi Sun <redacted>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
net/vmw_vsock/virtio_transport_common.c | 40 ++++++++-----------------
1 file changed, 12 insertions(+), 28 deletions(-)
From: Bobby Eshleman <hidden> Date: 2026-05-08 22:22:43
On Fri, May 08, 2026 at 06:44:10PM +0200, Stefano Garzarella wrote:
quoted hunk
From: Stefano Garzarella <sgarzare@redhat.com>
virtio_transport_build_skb() builds a new skb to be delivered to the
vsockmon tap device. To build the new skb, it uses the original skb
data length as payload length, but as the comment notes, the original
packet stored in the skb may have been split in multiple packets, so we
need to use the length in the header, which is correctly updated before
the packet is delivered to the tap, and the offset for the data.
This was also similar to what we did before commit 71dc9ec9ac7d
("virtio/vsock: replace virtio_vsock_pkt with sk_buff") where we probably
missed something during the skb conversion.
Also update the comment above, which was left stale by the skb
conversion and still mentioned a buffer pointer that no longer exists.
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
net/vmw_vsock/virtio_transport_common.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
@@ -166,12 +166,12 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)structsk_buff*skb;size_tpayload_len;-/* A packet could be split to fit the RX buffer, so we can retrieve-*thepayloadlengthfromtheheaderandthebufferpointertaking-*careoftheoffsetintheoriginalpacket.+/* A packet could be split to fit the RX buffer, so we use+*thepayloadlengthfromtheheader,whichhasbeenupdated+*bythesendertoreflectthefragmentsize.*/pkt_hdr=virtio_vsock_hdr(pkt);-payload_len=pkt->len;+payload_len=le32_to_cpu(pkt_hdr->len);skb=alloc_skb(sizeof(*hdr)+sizeof(*pkt_hdr)+payload_len,GFP_ATOMIC);
From: Bobby Eshleman <hidden> Date: 2026-05-08 22:30:37
On Fri, May 08, 2026 at 06:44:11PM +0200, Stefano Garzarella wrote:
quoted hunk
From: Stefano Garzarella <sgarzare@redhat.com>
For non-linear skbs, virtio_transport_build_skb() goes through
virtio_transport_copy_nonlinear_skb() to copy the original payload
in the new skb to be delivered to the vsockmon tap device.
This manually initializes an iov_iter but does not set iov_iter.count.
Since the iov_iter is zero-initialized, the copy length is zero and no
payload is actually copied to the monitor interface, leaving data
un-initialized.
Fix this by removing the linear vs non-linear split and using
skb_copy_datagram_iter() with iov_iter_kvec() for all cases, as
vhost-vsock already does. This handles both linear and non-linear skbs,
properly initializes the iov_iter, and removes the now unused
virtio_transport_copy_nonlinear_skb().
While touching this code, let's also check the return value of
skb_copy_datagram_iter(), even though it's unlikely to fail.
Fixes: 4b0bf10eb077 ("vsock/virtio: non-linear skb handling for tap")
Reported-by: Yiqi Sun <redacted>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
net/vmw_vsock/virtio_transport_common.c | 40 ++++++++-----------------
1 file changed, 12 insertions(+), 28 deletions(-)
From: "Michael S. Tsirkin" <mst@redhat.com> Date: 2026-05-09 19:38:15
On Fri, May 08, 2026 at 06:44:09PM +0200, Stefano Garzarella wrote:
While reviewing the patch posted by Yiqi Sun [1] to fix an issue in
virtio_transport_build_skb(), I discovered another issue related to
the offset and length of the payload to be copied in the new skb.
This was introduced when we did the skb conversion, and fixed by
patch 1.
Patch 2 fixes the issue found by Yiqi Sun in a different way: using
iov_iter_kvec() to properly initialize all the iov_iter fields and
removing the linear vs non-linear split like we alredy do in
vhost-vsock.
It could have been a single patch, but since there were two affected
commits, I decided to keep the fixes separate.
[1] https://lore.kernel.org/netdev/20260430071110.380509-1-sunyiqixm@gmail.com/
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Stefano Garzarella (2):
vsock/virtio: fix length and offset in tap skb for split packets
vsock/virtio: fix empty payload in tap skb for non-linear buffers
net/vmw_vsock/virtio_transport_common.c | 47 +++++++++----------------
1 file changed, 16 insertions(+), 31 deletions(-)
--
2.54.0
From: Stefano Garzarella <sgarzare@redhat.com>
virtio_transport_build_skb() builds a new skb to be delivered to the
vsockmon tap device. To build the new skb, it uses the original skb
data length as payload length, but as the comment notes, the original
packet stored in the skb may have been split in multiple packets, so we
need to use the length in the header, which is correctly updated before
the packet is delivered to the tap, and the offset for the data.
This was also similar to what we did before commit 71dc9ec9ac7d
("virtio/vsock: replace virtio_vsock_pkt with sk_buff") where we probably
missed something during the skb conversion.
Also update the comment above, which was left stale by the skb
conversion and still mentioned a buffer pointer that no longer exists.
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
net/vmw_vsock/virtio_transport_common.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
@@ -166,12 +166,12 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)structsk_buff*skb;size_tpayload_len;-/* A packet could be split to fit the RX buffer, so we can retrieve-*thepayloadlengthfromtheheaderandthebufferpointertaking-*careoftheoffsetintheoriginalpacket.+/* A packet could be split to fit the RX buffer, so we use+*thepayloadlengthfromtheheader,whichhasbeenupdated+*bythesendertoreflectthefragmentsize.*/pkt_hdr=virtio_vsock_hdr(pkt);-payload_len=pkt->len;+payload_len=le32_to_cpu(pkt_hdr->len);skb=alloc_skb(sizeof(*hdr)+sizeof(*pkt_hdr)+payload_len,GFP_ATOMIC);
From: Stefano Garzarella <sgarzare@redhat.com>
For non-linear skbs, virtio_transport_build_skb() goes through
virtio_transport_copy_nonlinear_skb() to copy the original payload
in the new skb to be delivered to the vsockmon tap device.
This manually initializes an iov_iter but does not set iov_iter.count.
Since the iov_iter is zero-initialized, the copy length is zero and no
payload is actually copied to the monitor interface, leaving data
un-initialized.
Fix this by removing the linear vs non-linear split and using
skb_copy_datagram_iter() with iov_iter_kvec() for all cases, as
vhost-vsock already does. This handles both linear and non-linear skbs,
properly initializes the iov_iter, and removes the now unused
virtio_transport_copy_nonlinear_skb().
While touching this code, let's also check the return value of
skb_copy_datagram_iter(), even though it's unlikely to fail.
Fixes: 4b0bf10eb077 ("vsock/virtio: non-linear skb handling for tap")
Reported-by: Yiqi Sun <redacted>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
net/vmw_vsock/virtio_transport_common.c | 40 ++++++++-----------------
1 file changed, 12 insertions(+), 28 deletions(-)
Hello:
This series was applied to netdev/net.git (main)
by Paolo Abeni [off-list ref]:
On Fri, 8 May 2026 18:44:09 +0200 you wrote:
While reviewing the patch posted by Yiqi Sun [1] to fix an issue in
virtio_transport_build_skb(), I discovered another issue related to
the offset and length of the payload to be copied in the new skb.
This was introduced when we did the skb conversion, and fixed by
patch 1.
Patch 2 fixes the issue found by Yiqi Sun in a different way: using
iov_iter_kvec() to properly initialize all the iov_iter fields and
removing the linear vs non-linear split like we alredy do in
vhost-vsock.
[...]