On Wed, Mar 4, 2026 at 3:29 AM Peter Maydell <[email protected]> wrote: > > 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: [email protected] > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3317 > Fixes: b43848a1005ce ("xilinx: Add ethlite emulation") > Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > hw/net/trace-events | 1 + > hw/net/xilinx_ethlite.c | 12 +++++++++--- > 2 files changed, 10 insertions(+), 3 deletions(-) > > diff --git a/hw/net/trace-events b/hw/net/trace-events > index 23efa91d05..001a20b0e2 100644 > --- a/hw/net/trace-events > +++ b/hw/net/trace-events > @@ -527,3 +527,4 @@ xen_netdev_rx(int dev, int idx, int status, int flags) > "vif%u idx %d status %d f > # xilinx_ethlite.c > ethlite_pkt_lost(uint32_t rx_ctrl) "rx_ctrl:0x%" PRIx32 > ethlite_pkt_size_too_big(uint64_t size) "size:0x%" PRIx64 > +ethlite_pkt_tx_size_too_big(uint64_t size) "size:0x%" PRIx64 > diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c > index ba3acd4c77..75e6520569 100644 > --- a/hw/net/xilinx_ethlite.c > +++ b/hw/net/xilinx_ethlite.c > @@ -162,9 +162,15 @@ static void port_tx_write(void *opaque, hwaddr addr, > uint64_t value, > break; > case TX_CTRL: > if ((value & (CTRL_P | CTRL_S)) == CTRL_S) { > - qemu_send_packet(qemu_get_queue(s->nic), > - txbuf_ptr(s, port_index), > - s->port[port_index].reg.tx_len); > + uint32_t size = s->port[port_index].reg.tx_len; > + > + if (size >= BUFSZ_MAX) { > + trace_ethlite_pkt_tx_size_too_big(size); > + } else { > + qemu_send_packet(qemu_get_queue(s->nic), > + txbuf_ptr(s, port_index), > + size); > + } > if (s->port[port_index].reg.tx_ctrl & CTRL_I) { > eth_pulse_irq(s); > } > -- > 2.43.0 > >
