|
| 1 | +From: Peter Maydell @ 2025-10-28 16:00 UTC (permalink / raw) |
| 2 | +To: qemu-devel; +Cc: Jason Wang, Bin Meng |
| 3 | + |
| 4 | +In commits like 969e50b61a28 ("net: Pad short frames to minimum size |
| 5 | +before sending from SLiRP/TAP") we switched away from requiring |
| 6 | +network devices to handle short frames to instead having the net core |
| 7 | +code do the padding of short frames out to the ETH_ZLEN minimum size. |
| 8 | +We then dropped the code for handling short frames from the network |
| 9 | +devices in a series of commits like 140eae9c8f7 ("hw/net: e1000: |
| 10 | +Remove the logic of padding short frames in the receive path"). |
| 11 | + |
| 12 | +This missed one route where the device's receive code can still see a |
| 13 | +short frame: if the device is in loopback mode and it transmits a |
| 14 | +short frame via the qemu_receive_packet() function, this will be fed |
| 15 | +back into its own receive code without being padded. |
| 16 | + |
| 17 | +Add the padding logic to qemu_receive_packet(). |
| 18 | + |
| 19 | +This fixes a buffer overrun which can be triggered in the |
| 20 | +e1000_receive_iov() logic via the loopback code path. |
| 21 | + |
| 22 | +Other devices that use qemu_receive_packet() to implement loopback |
| 23 | +are cadence_gem, dp8393x, lan9118, msf2-emac, pcnet, rtl8139 |
| 24 | +and sungem. |
| 25 | + |
| 26 | + |
| 27 | +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3043 |
| 28 | +Signed-off-by: Peter Maydell < [email protected]> |
| 29 | + |
| 30 | +Upstream Patch reference: https://lore.kernel.org/qemu-devel/ [email protected]/T/#u |
| 31 | +--- |
| 32 | + net/net.c | 10 ++++++++++ |
| 33 | + 1 file changed, 10 insertions(+) |
| 34 | + |
| 35 | +diff --git a/net/net.c b/net/net.c |
| 36 | +index 0520bc168..d6dc20835 100644 |
| 37 | +--- a/net/net.c |
| 38 | ++++ b/net/net.c |
| 39 | +@@ -755,10 +755,20 @@ ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size) |
| 40 | + |
| 41 | + ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size) |
| 42 | + { |
| 43 | ++ uint8_t min_pkt[ETH_ZLEN]; |
| 44 | ++ size_t min_pktsz = sizeof(min_pkt); |
| 45 | ++ |
| 46 | + if (!qemu_can_receive_packet(nc)) { |
| 47 | + return 0; |
| 48 | + } |
| 49 | + |
| 50 | ++ if (net_peer_needs_padding(nc)) { |
| 51 | ++ if (eth_pad_short_frame(min_pkt, &min_pktsz, buf, size)) { |
| 52 | ++ buf = min_pkt; |
| 53 | ++ size = min_pktsz; |
| 54 | ++ } |
| 55 | ++ } |
| 56 | ++ |
| 57 | + return qemu_net_queue_receive(nc->incoming_queue, buf, size); |
| 58 | + } |
| 59 | + |
| 60 | +-- |
| 61 | +2.45.4 |
| 62 | + |
0 commit comments