mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 03:24:19 +02:00
vsock/virtio: fix skb overhead accounting to preserve full buf_alloc
After commit059b7dbd20("vsock/virtio: fix potential unbounded skb queue"), virtio_transport_inc_rx_pkt() subtracts per-skb overhead from buf_alloc when checking whether a new packet fits. This reduces the effective receive buffer below what the user configured via SO_VM_SOCKETS_BUFFER_SIZE, causing legitimate data packets to be silently dropped and applications that rely on the full buffer size to deadlock. Also, the reduced space is not communicated to the remote peer, so its credit calculation accounts more credit than the receiver will actually accept, causing data loss (there is no retransmission). With this approach we currently have failures in tools/testing/vsock/vsock_test.c. Test 18 sometimes fails, while test 22 always fails in this way: 18 - SOCK_STREAM MSG_ZEROCOPY...hash mismatch 22 - SOCK_STREAM virtio credit update + SO_RCVLOWAT...send failed: Resource temporarily unavailable Fix by allowing at most `buf_alloc * 2` as the total budget for payload plus skb overhead in virtio_transport_inc_rx_pkt(), similar to how SO_RCVBUF is doubled to reserve space for sk_buff metadata. This preserves the full buf_alloc for payload under normal operation, while still bounding the skb queue growth. With this patch, all tests in tools/testing/vsock/vsock_test.c are now passing again. Fixes:059b7dbd20("vsock/virtio: fix potential unbounded skb queue") Cc: stable@vger.kernel.org Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Link: https://patch.msgid.link/20260518090656.134588-3-sgarzare@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
a4f0b00178
commit
c6087c5aaa
|
|
@ -419,7 +419,14 @@ static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
|
|||
{
|
||||
u64 skb_overhead = (skb_queue_len(&vvs->rx_queue) + 1) * SKB_TRUESIZE(0);
|
||||
|
||||
if (skb_overhead + vvs->buf_used + len > vvs->buf_alloc)
|
||||
/* Allow at most buf_alloc * 2 total budget (payload + overhead),
|
||||
* similar to how SO_RCVBUF is doubled to reserve space for sk_buff
|
||||
* metadata. Check payload against buf_alloc to be sure the other
|
||||
* peer is respecting the credit, and sk_buff overhead to bound
|
||||
* queue growth.
|
||||
*/
|
||||
if ((u64)vvs->buf_used + len > vvs->buf_alloc ||
|
||||
skb_overhead > vvs->buf_alloc)
|
||||
return false;
|
||||
|
||||
vvs->rx_bytes += len;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user