@samitouri / QOSamiQemu / commits / 6595a8d5d1

hw/net/xilinx_ethlite: Check for oversized TX packets

The xilinx_ethlite network device wasn't checking that the TX packet size set by the guest was within the size of its dual port RAM, with the effect that the guest could get it to read off the end of the RAM block. Check the length. There is no provision in this very simple device for reporting errors, so as with various RX errors we just report via tracepoint. This lack of length check has been present since the device was first introduced, though the code implementing the tx path has changed somewhat since then. Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3317 Fixes: b43848a1005ce ("xilinx: Add ethlite emulation") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> Message-ID: <20260303172718.437015-1-peter.maydell@linaro.org> [PMD: renamed size -> tx_size to avoid shadow=compatible-local error] Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Peter Maydell committed Mar 3, 2026 at 17:27 UTC 6595a8d5d17ea1716ddafb34455ec2b29381e232
2 files changed +10 -3
hw/net/trace-events
+1
@@ -527,3 +527,4 @@ xen_netdev_rx(int dev, int idx, int status, int flags) "vif%u idx %d status %d f
527 # xilinx_ethlite.c
528 ethlite_pkt_lost(uint32_t rx_ctrl) "rx_ctrl:0x%" PRIx32
529 ethlite_pkt_size_too_big(uint64_t size) "size:0x%" PRIx64
530 +ethlite_pkt_tx_size_too_big(uint64_t size) "size:0x%" PRIx64
hw/net/xilinx_ethlite.c
+9 -3
@@ -162,9 +162,15 @@ static void port_tx_write(void *opaque, hwaddr addr, uint64_t value,
162 break;
163 case TX_CTRL:
164 if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
165 - qemu_send_packet(qemu_get_queue(s->nic),
166 - txbuf_ptr(s, port_index),
167 - s->port[port_index].reg.tx_len);
165 + uint32_t tx_size = s->port[port_index].reg.tx_len;
166 +
167 + if (tx_size >= BUFSZ_MAX) {
168 + trace_ethlite_pkt_tx_size_too_big(tx_size);
169 + } else {
170 + qemu_send_packet(qemu_get_queue(s->nic),
171 + txbuf_ptr(s, port_index),
172 + tx_size);
173 + }
174 if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
175 eth_pulse_irq(s);
176 }