On Mon, Apr 20, 2026 at 03:20:51PM +0200, Stefano Garzarella wrote: > From: Stefano Garzarella <[email protected]> > > virtio_transport_init_zcopy_skb() uses iter->count as the size argument > for msg_zerocopy_realloc(), which in turn passes it to > mm_account_pinned_pages() for RLIMIT_MEMLOCK accounting. However, this > function is called after virtio_transport_fill_skb() has already consumed > the iterator via __zerocopy_sg_from_iter(), so on the last skb, iter->count > will be 0, skipping the RLIMIT_MEMLOCK enforcement. > > Pass pkt_len (the total bytes being sent) as an explicit parameter to > virtio_transport_init_zcopy_skb() instead of reading the already-consumed > iter->count. > > This matches TCP and UDP, which both call msg_zerocopy_realloc() with > the original message size. > > Fixes: 581512a6dc93 ("vsock/virtio: MSG_ZEROCOPY flag support") > Reported-by: Yiming Qian <[email protected]> > Signed-off-by: Stefano Garzarella <[email protected]> > --- > net/vmw_vsock/virtio_transport_common.c | 11 ++++++++--- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/net/vmw_vsock/virtio_transport_common.c > b/net/vmw_vsock/virtio_transport_common.c > index 0742091beae7..416d533f493d 100644 > --- a/net/vmw_vsock/virtio_transport_common.c > +++ b/net/vmw_vsock/virtio_transport_common.c > @@ -73,6 +73,7 @@ static bool virtio_transport_can_zcopy(const struct > virtio_transport *t_ops, > static int virtio_transport_init_zcopy_skb(struct vsock_sock *vsk, > struct sk_buff *skb, > struct msghdr *msg, > + size_t pkt_len, > bool zerocopy) > { > struct ubuf_info *uarg; > @@ -81,12 +82,10 @@ static int virtio_transport_init_zcopy_skb(struct > vsock_sock *vsk, > uarg = msg->msg_ubuf; > net_zcopy_get(uarg); > } else { > - struct iov_iter *iter = &msg->msg_iter; > struct ubuf_info_msgzc *uarg_zc; > > uarg = msg_zerocopy_realloc(sk_vsock(vsk), > - iter->count, > - NULL, false); > + pkt_len, NULL, false); > if (!uarg) > return -1; > > @@ -398,11 +397,17 @@ static int virtio_transport_send_pkt_info(struct > vsock_sock *vsk, > * each iteration. If this is last skb for this buffer > * and MSG_ZEROCOPY mode is in use - we must allocate > * completion for the current syscall. > + * > + * Pass pkt_len because msg iter is already consumed > + * by virtio_transport_fill_skb(), so iter->count > + * can not be used for RLIMIT_MEMLOCK pinned-pages > + * accounting done by msg_zerocopy_realloc(). > */ > if (info->msg && info->msg->msg_flags & MSG_ZEROCOPY && > skb_len == rest_len && info->op == VIRTIO_VSOCK_OP_RW) { > if (virtio_transport_init_zcopy_skb(vsk, skb, > info->msg, > + pkt_len, > can_zcopy)) { > kfree_skb(skb); > ret = -ENOMEM; > -- > 2.53.0 >
Reviewed-by: Bobby Eshleman <[email protected]>

