Re: [PATCH] hw/net/xilinx_ethlite: Check for oversized TX packets

2026-03-08 Thread Philippe Mathieu-Daudé

On 3/3/26 18:27, Peter Maydell 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 
---
  hw/net/trace-events |  1 +
  hw/net/xilinx_ethlite.c | 12 +---
  2 files changed, 10 insertions(+), 3 deletions(-)




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);
  }


Patch queued renaming @size -> @tx_size to prevent:

../hw/net/xilinx_ethlite.c: In function ‘port_tx_write’:
../hw/net/xilinx_ethlite.c:165:22: error: declaration of ‘size’ shadows 
a parameter [-Werror=shadow=compatible-local]

  165 | uint32_t size = s->port[port_index].reg.tx_len;
  |  ^~~~
../hw/net/xilinx_ethlite.c:151:40: note: shadowed declaration is here
  151 |   unsigned int size)
  |   ~^~~~




Re: [PATCH] hw/net/xilinx_ethlite: Check for oversized TX packets

2026-03-03 Thread Alistair Francis
On Wed, Mar 4, 2026 at 3:29 AM Peter Maydell  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 

Reviewed-by: Alistair Francis 

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
>
>



Re: [PATCH] hw/net/xilinx_ethlite: Check for oversized TX packets

2026-03-03 Thread Edgar E. Iglesias
On Tue, Mar 03, 2026 at 05:27:18PM +, Peter Maydell 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 

Reviewed-by: Edgar E. Iglesias 



> ---
>  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
>