The TBCIR (Transmit Buffer Descriptor Ring Consumer Index) register has the BD index as the lower 16 bits, but the upper 16 bits contain this field: STAT_ID: Status identifier. Incremented each time the BDR_INDEX is updated and an error status bit was set for one of the processed BDs. Clears on read. If there was any transmit error prior to the ring reinitialization and this is the first time we re-read the TBCIR register, reading it will give us a value with non-zero upper bits, which is saved in bdr->next_to_clean. If subsequently NAPI gets invoked and enetc_clean_tx_ring() runs, this will dereference the &tx_ring->tx_swbd[] for the bogus (and huge) next_to_clean index, and will result in an out-of-bounds memory access. Other places like enetc_bd_ready_count() do mask out the upper bits, so let's do that here as well. Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") Signed-off-by: Vladimir Oltean --- drivers/net/ethernet/freescale/enetc/enetc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index a146ceaf2ed6..c9cdf9d11212 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -2593,7 +2593,8 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) /* clearing PI/CI registers for Tx not supported, adjust sw indexes */ tx_ring->next_to_use = enetc_txbdr_rd(hw, idx, ENETC_TBPIR); - tx_ring->next_to_clean = enetc_txbdr_rd(hw, idx, ENETC_TBCIR); + tx_ring->next_to_clean = enetc_txbdr_rd(hw, idx, ENETC_TBCIR) & + ENETC_TBCIR_IDX_MASK; /* enable Tx ints by setting pkt thr to 1 */ enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1); -- 2.43.0