@samitouri / QOSamiQemu / commits / 550391c713

hw/net/npcm_gmac: Catch accesses off the end of the register array

In the npcm_gmac device, we create the iomem MemoryRegion with a size of 8KB, but NPCM_GMAC_NR_REGS is only 0x1060 / 4. This means there's a range of offsets that the guest can access that don't have gmac->regs[] entries. We weren't catching this, so the guest could get us to index off the end of the regs array. Catch and log these invalid accesses. Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3316 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260306154016.2194091-1-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Peter Maydell committed Mar 6, 2026 at 15:40 UTC 550391c7134d295d73b2b0e7a1111a922b78c13c
2 files changed +16 -1
hw/net/npcm_gmac.c
+14
@@ -700,6 +700,13 @@ static uint64_t npcm_gmac_read(void *opaque, hwaddr offset, unsigned size)
700 NPCMGMACState *gmac = opaque;
701 uint32_t v = 0;
702
703 + if (offset >= NPCM_GMAC_REG_SIZE) {
704 + qemu_log_mask(LOG_GUEST_ERROR,
705 + "%s: invalid register offset: 0x%04" HWADDR_PRIx"\n",
706 + DEVICE(gmac)->canonical_path, offset);
707 + return v;
708 + }
709 +
710 switch (offset) {
711 /* Write only registers */
712 case A_NPCM_DMA_XMT_POLL_DEMAND:
@@ -724,6 +731,13 @@ static void npcm_gmac_write(void *opaque, hwaddr offset,
731
732 trace_npcm_gmac_reg_write(DEVICE(gmac)->canonical_path, offset, v);
733
734 + if (offset >= NPCM_GMAC_REG_SIZE) {
735 + qemu_log_mask(LOG_GUEST_ERROR,
736 + "%s: invalid register offset: 0x%04" HWADDR_PRIx"\n",
737 + DEVICE(gmac)->canonical_path, offset);
738 + return;
739 + }
740 +
741 switch (offset) {
742 /* Read only registers */
743 case A_NPCM_GMAC_VERSION:
include/hw/net/npcm_gmac.h
+2 -1
@@ -24,7 +24,8 @@
24 #include "hw/core/sysbus.h"
25 #include "net/net.h"
26
27 -#define NPCM_GMAC_NR_REGS (0x1060 / sizeof(uint32_t))
27 +#define NPCM_GMAC_REG_SIZE 0x1060
28 +#define NPCM_GMAC_NR_REGS (NPCM_GMAC_REG_SIZE / sizeof(uint32_t))
29
30 #define NPCM_GMAC_MAX_PHYS 32
31 #define NPCM_GMAC_MAX_PHY_REGS 32