@samitouri / QOSamiQemu / commits / b1e73b2ddb

net: Correct padding check in qemu_receive_packet()

In qemu_receive_packet() we check to see if we should pad a short packet. This is doing the wrong test: because this function is used when the device adds a packet to its own incoming queue (i.e. for loopback), we should be checking the NetClientState's own do_not_pad flag, not that for its peer. We didn't notice this earlier, because at the moment all the real peers of a network device (i.e. the network backends) do not set do_not_pad, so net_peer_needs_padding() always returns true except in the corner case where the network device has no peer at all. The effect of this is that if a network device has no peer (e.g. because QEMU was started with -net none or with -nodefaults) then we can still let through the kind of "guest misprograms the network device to loopback-transmit a short packet and then we mishandle it in the receive path" bug like #3043 which commit a01344d9d78 was trying to fix. Since the distinction between "we should check nc->do_not_pad" and "we should check nc->peer->do_not_pad" is a bit subtle, add enough documentation commentary to make it more obvious. Cc: qemu-stable@nongnu.org Fixes: a01344d9d78 ("net: pad packets to minimum length in qemu_receive_packet()") Suggested-by: Bin Meng <bmeng.cn@gmail.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Bin Meng <bin.meng@processmission.com> Message-ID: <20260629164246.2028947-1-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

Peter Maydell committed Jun 29, 2026 at 17:42 UTC b1e73b2ddbb2850e394b9c47cfcb14dba8048a71
2 files changed +24 -1
include/net/net.h
+23
@@ -349,9 +349,32 @@ uint32_t net_crc32_le(const uint8_t *p, int len);
349 .offset = vmstate_offset_macaddr(_state, _field), \
350 }
351
352 +/**
353 + * net_peer_needs_padding: Should we pad as we send out packets?
354 + * @nc: NetClientState
355 + *
356 + * Return true if the peer of this NetClientState (i.e. the
357 + * destination that qemu_send_packet() etc send to) requires us to pad
358 + * out packets that are shorter than the minimum ethernet frame
359 + * length.
360 + */
361 static inline bool net_peer_needs_padding(NetClientState *nc)
362 {
363 return nc->peer && !nc->peer->do_not_pad;
364 }
365
366 +/**
367 + * net_client_needs_padding: Should we pad as we queue packets to ourselves?
368 + * @nc: NetClientState
369 + *
370 + * Return true if this NetClientState requires us to pad out packets
371 + * that are shorter than the minimum ethernet frame length. This is
372 + * the check to make in qemu_receive_packet() when we are queuing a
373 + * packet back into ourselves (i.e. loopback).
374 + */
375 +static inline bool net_client_needs_padding(NetClientState *nc)
376 +{
377 + return !nc->do_not_pad;
378 +}
379 +
380 #endif
net/net.c
+1 -1
@@ -783,7 +783,7 @@ ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size)
783 return 0;
784 }
785
786 - if (net_peer_needs_padding(nc)) {
786 + if (net_client_needs_padding(nc)) {
787 if (eth_pad_short_frame(min_pkt, &min_pktsz, buf, size)) {
788 buf = min_pkt;
789 size = min_pktsz;