--- a/sys/dev/netif/mxge/if_mxge.c +++ b/sys/dev/netif/mxge/if_mxge.c @@ -1137,6 +1137,17 @@ } #endif +/* + * Firmware-returned SRAM offsets are device-supplied; every pointer we + * later PIO-write through must lie inside the mapped SRAM BAR window. + */ +static __inline int +mxge_sram_range_valid(const mxge_softc_t *sc, uint32_t off, uint32_t len) +{ + return (off <= (uint32_t)sc->sram_size && + len <= (uint32_t)sc->sram_size - off); +} + static int mxge_reset(mxge_softc_t *sc, int interrupts_setup) { @@ -1220,12 +1231,18 @@ status |= mxge_send_cmd(sc, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd); + if (status == 0 && !mxge_sram_range_valid(sc, cmd.data0, 4)) + status = ENXIO; sc->intr_coal_delay_ptr = (volatile uint32_t *)(sc->sram + cmd.data0); status |= mxge_send_cmd(sc, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd); + if (status == 0 && !mxge_sram_range_valid(sc, cmd.data0, 8)) + status = ENXIO; irq_claim = (volatile uint32_t *)(sc->sram + cmd.data0); status |= mxge_send_cmd(sc, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd); + if (status == 0 && !mxge_sram_range_valid(sc, cmd.data0, 4)) + status = ENXIO; sc->irq_deassert = (volatile uint32_t *)(sc->sram + cmd.data0); if (status != 0) { @@ -3290,6 +3307,11 @@ cmd.data0 = slice; err = mxge_send_cmd(ss->sc, MXGEFW_CMD_GET_SEND_OFFSET, &cmd); + if (err == 0 && + !mxge_sram_range_valid(ss->sc, cmd.data0, + (ss->tx.mask + 1) * + sizeof(mcp_kreq_ether_send_t))) + err = ENXIO; ss->tx.lanai = (volatile mcp_kreq_ether_send_t *) (ss->sc->sram + cmd.data0); /* Leave send_go and send_stop as NULL */ @@ -3297,6 +3319,10 @@ } else { cmd.data0 = slice; err = mxge_send_cmd(ss->sc, MXGEFW_CMD_GET_SEND_OFFSET, &cmd); + if (err == 0 && + !mxge_sram_range_valid(ss->sc, cmd.data0, + (ss->tx.mask + 1) * sizeof(mcp_kreq_ether_send_t))) + err = ENXIO; ss->tx.lanai = (volatile mcp_kreq_ether_send_t *) (ss->sc->sram + cmd.data0); ss->tx.send_go = (volatile uint32_t *) @@ -3307,11 +3333,19 @@ cmd.data0 = slice; err |= mxge_send_cmd(ss->sc, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd); + if (err == 0 && + !mxge_sram_range_valid(ss->sc, cmd.data0, + (ss->rx_data.rx_small.mask + 1) * sizeof(mcp_kreq_ether_recv_t))) + err = ENXIO; ss->rx_data.rx_small.lanai = (volatile mcp_kreq_ether_recv_t *)(ss->sc->sram + cmd.data0); cmd.data0 = slice; err |= mxge_send_cmd(ss->sc, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd); + if (err == 0 && + !mxge_sram_range_valid(ss->sc, cmd.data0, + (ss->rx_data.rx_big.mask + 1) * sizeof(mcp_kreq_ether_recv_t))) + err = ENXIO; ss->rx_data.rx_big.lanai = (volatile mcp_kreq_ether_recv_t *)(ss->sc->sram + cmd.data0); @@ -3393,6 +3427,10 @@ } itable = sc->sram + cmd.data0; + if (!mxge_sram_range_valid(sc, cmd.data0, NETISR_CPUMAX)) { + if_printf(ifp, "bad RSS table offset 0x%x\n", cmd.data0); + return EIO; + } for (i = 0; i < NETISR_CPUMAX; i++) itable[i] = sc->rdr_table[i]; @@ -3410,6 +3448,12 @@ return err; } hwkey = sc->sram + cmd.data0; + if (!mxge_sram_range_valid(sc, cmd.data0, + MXGE_HWRSS_KEYLEN)) { + if_printf(ifp, "bad RSS key offset 0x%x\n", + cmd.data0); + return EIO; + } toeplitz_get_key(swkey, MXGE_HWRSS_KEYLEN); for (i = 0; i < MXGE_HWRSS_KEYLEN; ++i)