> 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: [email protected]
> Assisted-by: LLM
> Signed-off-by: Daehyeon Ko <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review ยท
https://sashiko.dev/#/patchset/[email protected]?part=1