Describe the bug
When running a container with krun as the OCI runtime and a guest kernel ≥ 6.2, any application sending sufficiently large data over TCP causes the vsock device to log:
ERROR krun_devices::virtio::vsock::device] error reading TX packet: BufDescTooSmall
The connection is silently dropped and retried indefinitely. The application never completes its request.
Root cause
The guest kernel splits large TX packets across multiple chained descriptors. Specifically, a 64KB packet (pkt.len = 65536, which is MAX_PKT_BUF_SIZE) is split into two 32KB descriptors (buf_desc.len = 32768).
The current from_tx_virtq_head() in src/devices/src/virtio/vsock/packet.rs only reads the first data descriptor and checks its length against pkt.len():
if buf_desc.len < pkt.len() {
return Err(VsockError::BufDescTooSmall); // always fails for 64KB packets
}
Since 32768 < 65536, it always fails. The code never traverses the rest of the descriptor chain.
Note: a related single-descriptor TX fix (mirroring the Linux ≥ 6.2 RX fix) was already applied and does not address this case — the error now comes specifically from the two-descriptor split path (head.has_next=true).
Debug log confirming the values
ERROR krun_devices::virtio::vsock::packet] BufDescTooSmall: buf_desc.len=32768 pkt.len=65536 head.has_next=true
Steps to reproduce
- Run a container with
--runtime krun with a Linux ≥ 6.x guest kernel
- Inside the container, make any large HTTPS request with a body ≥ 64KB (e.g. GitHub Copilot CLI
gh copilot, which sends large JSON payloads containing tool definitions)
- Observe repeated BufDescTooSmall errors
Environment
- libkrun: 1.18.0 (with single-descriptor TX patch applied)
- Guest kernel: 6.12.68
- Host OS: Linux (openSUSE)
- Reproducible with:
gh copilot -p "..." — sends 64KB HTTP request bodies. Applications with smaller payloads are not affected.
Expected behavior
from_tx_virtq_head() should traverse the full descriptor chain and accumulate the total available buffer length, mirroring how the RX path handles chained descriptors.
Describe the bug
When running a container with krun as the OCI runtime and a guest kernel ≥ 6.2, any application sending sufficiently large data over TCP causes the vsock device to log:
The connection is silently dropped and retried indefinitely. The application never completes its request.
Root cause
The guest kernel splits large TX packets across multiple chained descriptors. Specifically, a 64KB packet (
pkt.len = 65536, which isMAX_PKT_BUF_SIZE) is split into two 32KB descriptors (buf_desc.len = 32768).The current
from_tx_virtq_head()insrc/devices/src/virtio/vsock/packet.rsonly reads the first data descriptor and checks its length againstpkt.len():Since
32768 < 65536, it always fails. The code never traverses the rest of the descriptor chain.Note: a related single-descriptor TX fix (mirroring the Linux ≥ 6.2 RX fix) was already applied and does not address this case — the error now comes specifically from the two-descriptor split path (
head.has_next=true).Debug log confirming the values
Steps to reproduce
--runtime krunwith a Linux ≥ 6.x guest kernelgh copilot, which sends large JSON payloads containing tool definitions)Environment
gh copilot -p "..."— sends 64KB HTTP request bodies. Applications with smaller payloads are not affected.Expected behavior
from_tx_virtq_head()should traverse the full descriptor chain and accumulate the total available buffer length, mirroring how the RX path handles chained descriptors.