The generic timestamp_interrupt() handler derives the EXTTS channel index with ilog2() applied directly to the PTP_ACR channel mask, with no check for a zero mask. ilog2(0) yields -1, which ends up in event.index as 0xffffffff, and ptp_clock_event() uses that index in test_bit() against a PTP_MAX_CHANNELS bitmap without range validation, reading far past the allocation from hard IRQ context. The zero-mask window is reachable: stmmac_enable() sets STMMAC_FLAG_EXT_SNAPSHOT_EN before it programs PTP_ACR, so an EXTTS interrupt arriving in between passes the flag check while the mask is still clear (snapshots can also linger in the FIFO from a previous enable, as only PTP_ACR_ATSFC clears them). Check the mask before applying the ilog2(). Fixes: 8851346912a1 ("net: stmmac: Assign configured channel value to EXTTS event") Cc: stable@vger.kernel.org Signed-off-by: Zxyan Zhu --- drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c index 870c740b4a50..fd1142344950 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c @@ -245,7 +245,10 @@ static void timestamp_interrupt(struct stmmac_priv *priv) GMAC_TIMESTAMP_ATSNS_SHIFT; acr_value = readl(priv->ptpaddr + PTP_ACR); - channel = ilog2(FIELD_GET(PTP_ACR_MASK, acr_value)); + channel = FIELD_GET(PTP_ACR_MASK, acr_value); + if (!channel) + return; + channel = ilog2(channel); for (i = 0; i < num_snapshot; i++) { read_lock_irqsave(&priv->ptp_lock, flags); -- 2.34.1