DF-3720 / fix.diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | --- 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) |