[PATCH net-next v11 1/9] net: macb: close race between NAPI polls & ndo_stop

From: Théo Lebrun

Date: Tue Oct 13 2026 - 12:18:31 EST


In ndo_close, we call napi_disable() then free the ring buffers
queue->rx_ring|tx_ring. In the NAPI poll functions, after
napi_complete_done() we might enable interrupts and might re-check the
next ring buffer slot.

This is a use-after-free race on our ring buffers because napi_disable()
only waits for napi_complete_done() to return, it does not wait for
NAPI poll functions to finish.

The poll function sequence must stay as-is, see commit 0bf476fc3624
("net: macb: Fix lost RX packet wakeup race in NAPI receive") which
explains why the sequence must be napi_complete_done() -> arm IRQs
-> re-check ring slot.

Fix by waiting for full end of NAPI poll functions using
synchronize_net() in our ndo_close implementation.

This bug has never been reproduced and was reported by Sashiko. The
chances of facing it in practice sound tiny: it needs a system without
any phylink attached, running PREEMPT_RT and with a kernel preemption
on the NAPI poll at the right instant.

We fix it here before introducing context swapping, which is another
place where the race could appear (and Sashiko complains on this
series).

Fixes: 138badbc21a0 ("net: macb: use NAPI for TX completion path")
Fixes: 1900e30d0ef7 ("net: macb: simplify/cleanup NAPI reschedule checking")
Cc: stable+noautosel@xxxxxxxxxx # too unlikely and never reported by users
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261001-macb-context-v10-0-beb541bbb7df%40bootlin.com?part=7
Link: https://lore.kernel.org/all/179115680572.434549.1016291990685937691@xxxxxxxxxx/
Signed-off-by: Théo Lebrun <theo.lebrun@xxxxxxxxxxx>
---
drivers/net/ethernet/cadence/macb_main.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 020a47353d01..d414d00d93ce 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -2059,6 +2059,12 @@ static void macb_quiesce_start(struct macb *bp)
napi_disable(&queue->napi_tx);
}

+ /* NAPI instances still access Rx/Tx rings after their
+ * napi_complete_done() calls! Callers to macb_quiesce_start()
+ * free rings, so wait for all NAPI handlers to be done.
+ */
+ synchronize_net();
+
/* Must be done after napi_tx is disabled: its completion re-arms
* the LPI timer.
*/

--
2.56.0