Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vsock/virtio: fix MSG_ZEROCOPY pinned-pages accounting

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 <yimingqian591@gmail.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>
Link: https://patch.msgid.link/20260420132051.217589-1-sgarzare@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Stefano Garzarella and committed by
Paolo Abeni
1cb36e25 42ea37b0

+8 -3
+8 -3
net/vmw_vsock/virtio_transport_common.c
··· 73 73 static int virtio_transport_init_zcopy_skb(struct vsock_sock *vsk, 74 74 struct sk_buff *skb, 75 75 struct msghdr *msg, 76 + size_t pkt_len, 76 77 bool zerocopy) 77 78 { 78 79 struct ubuf_info *uarg; ··· 82 81 uarg = msg->msg_ubuf; 83 82 net_zcopy_get(uarg); 84 83 } else { 85 - struct iov_iter *iter = &msg->msg_iter; 86 84 struct ubuf_info_msgzc *uarg_zc; 87 85 88 86 uarg = msg_zerocopy_realloc(sk_vsock(vsk), 89 - iter->count, 90 - NULL, false); 87 + pkt_len, NULL, false); 91 88 if (!uarg) 92 89 return -1; 93 90 ··· 397 398 * each iteration. If this is last skb for this buffer 398 399 * and MSG_ZEROCOPY mode is in use - we must allocate 399 400 * completion for the current syscall. 401 + * 402 + * Pass pkt_len because msg iter is already consumed 403 + * by virtio_transport_fill_skb(), so iter->count 404 + * can not be used for RLIMIT_MEMLOCK pinned-pages 405 + * accounting done by msg_zerocopy_realloc(). 400 406 */ 401 407 if (info->msg && info->msg->msg_flags & MSG_ZEROCOPY && 402 408 skb_len == rest_len && info->op == VIRTIO_VSOCK_OP_RW) { 403 409 if (virtio_transport_init_zcopy_skb(vsk, skb, 404 410 info->msg, 411 + pkt_len, 405 412 can_zcopy)) { 406 413 kfree_skb(skb); 407 414 ret = -ENOMEM;