-
Notifications
You must be signed in to change notification settings - Fork 182
net_tap / net_dio: RX write path does not check buffer capacity before writing #3120
Description
Problem
The TAP and DIO network backends call write_packet() on the BufferAccess pool without first checking capacity(). If a guest posts a small RX descriptor, the backend will attempt to write a full-size frame into it.
With the capacity() fix in #3119, write_header now asserts that metadata.len <= packet.cap. Since packet.cap is derived from the guest-provided descriptor size, a guest posting an undersized RX buffer will trigger this assert and crash the VMM when using TAP or DIO backends.
Affected code
net_tap — vm/devices/net/net_tap/src/lib.rs around line 265:
self.inner.pool.write_packet(
rx,
&RxMetadata { offset: 0, len: frame_len, ..rx_meta },
&self.buffer[frame_start..read_len],
);net_dio — vm/devices/net/net_dio/src/lib.rs around line 144:
self.rx_pool.write_packet(
id,
&RxMetadata { offset: 0, len: buf.len(), ..Default::default() },
buf,
);Neither checks capacity(rx_id) before writing.
Fix
Both backends should check capacity() before calling write_packet(). If the frame exceeds the buffer capacity, either drop the packet (and return the RxId to the available pool) or truncate to the buffer size.
Consomme already does this correctly — its recv() implementation checks data.len() <= capacity(rx_id) and returns oversized buffers to rx_avail.
Impact
Guest-triggered VMM panic (DoS) when using TAP or DIO backends with a malicious or buggy guest driver that posts undersized RX descriptors.