On 4/30/26 9:11 AM, Yiqi Sun wrote:
> vsockmon mirrors packets through virtio_transport_build_skb(), which
> builds a new skb and copies the payload into it. For non-linear skbs,
> this goes through virtio_transport_copy_nonlinear_skb().
>
> Helper manually initializes a iov_iter, but leaves iov_iter.count unset.
> As a result, skb_copy_datagram_iter() sees zero writable bytes
> in the destination iterator and copies no payload data.
>
> This becomes an info leak because virtio_transport_build_skb() has
> already reserved payload_len bytes in the new skb with skb_put(). The
> skb is then returned to the tap path with that payload area still
> uninitialized, so userspace reading from a vsockmon device can observe
> heap contents and potentially kernel address.
>
> Fix it by initializing iov_iter.count to the number of bytes to copy.
>
> Fixes: 4b0bf10eb077 ("vsock/virtio: non-linear skb handling for tap")
> Signed-off-by: Yiqi Sun <[email protected]>
> ---
> net/vmw_vsock/virtio_transport_common.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/vmw_vsock/virtio_transport_common.c
> b/net/vmw_vsock/virtio_transport_common.c
> index 416d533f493d..6b26ee57ccab 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -152,7 +152,7 @@ static void virtio_transport_copy_nonlinear_skb(const
> struct sk_buff *skb,
> iov_iter.nr_segs = 1;
>
> to_copy = min_t(size_t, len, skb->len);
> -
> + iov_iter.count = to_copy;
> skb_copy_datagram_iter(skb, VIRTIO_VSOCK_SKB_CB(skb)->offset,
> &iov_iter, to_copy);
@Stefano, @Stefan, the patch LGTM, but sashiko pointed out to a
pre-existing issue you should probably want to address:
> to_copy = min_t(size_t, len, skb->len);
Does this length calculation account for the offset when a packet is
split across multiple transmissions?
If a packet is requeued, VIRTIO_VSOCK_SKB_CB(skb)->offset is increased,
but to_copy still evaluates to the full length of the skb.
/P