From: Cédric Le Goater <[email protected]> Currently, DMA memory operation errors in the ftgmac100 model are not all tested and this can lead to a guest-triggerable denial of service as described in https://gitlab.com/qemu-project/qemu/-/work_items/3335.
To fix this, check the return value of ftgmac100_write_bd() in the TX path and exit the TX loop on error to prevent further processing. In the event of a DMA error, also set FTGMAC100_INT_AHB_ERR interrupt flag as appropriate. The FTGMAC100_INT_AHB_ERR interrupt status bit only applies to the AST2400 SoC; on newer Aspeed SoCs, it is a reserved bit. Nevertheless, since it is supported by the Linux driver and it should be safe to use in the QEMU implementation across all SoCs. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3335 Signed-off-by: Cédric Le Goater <[email protected]> Reviewed-by: Jamin Lin <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Message-ID: <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> (cherry picked from commit fa4a759fc1e19b2185becfadb00c6d8e57462849) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index 1f524d7a01..abfb47a824 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -624,7 +624,10 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint64_t tx_ring, bd.des0 &= ~FTGMAC100_TXDES0_TXDMA_OWN; /* Write back the modified descriptor. */ - ftgmac100_write_bd(&bd, addr); + if (ftgmac100_write_bd(&bd, addr)) { + s->isr |= FTGMAC100_INT_AHB_ERR; + break; + } /* Advance to the next descriptor. */ if (bd.des0 & s->txdes0_edotr) { addr = tx_ring; @@ -1134,7 +1137,10 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, bd.des0 |= flags | FTGMAC100_RXDES0_LRS; s->isr |= FTGMAC100_INT_RPKT_BUF; } - ftgmac100_write_bd(&bd, addr); + if (ftgmac100_write_bd(&bd, addr)) { + s->isr |= FTGMAC100_INT_AHB_ERR; + break; + } if (bd.des0 & s->rxdes0_edorr) { addr = s->rx_ring; } else { -- 2.47.3
