Thread (7 messages) flat view 7 messages, 3 authors, 7d ago
COOLING7d

[PATCH net v3 3/3] net: pse-pd: unregister from the controller list before freeing PI data

From: Carlo Szelinsky <hidden>
Date: 2026-08-13 20:07:42
Also in: lkml
Subsystem: networking drivers, pse network driver, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Oleksij Rempel, Kory Maincent, Linus Torvalds

pse_controller_unregister() frees the PI array with pse_release_pis()
while the controller is still linked on pse_controller_list, and only
removes it from the list afterwards. A concurrent consumer probe running
of_pse_control_get() walks that list under pse_list_mutex and calls
of_pse_match_pi(), which dereferences pcdev->pi[i].np. If the walk lands
on a controller that is being torn down, it reads the freed (with the
previous patch, NULLed) PI array.

Move the list_del() ahead of pse_release_pis(). Both the lookup and the
removal serialise on pse_list_mutex, so once the controller is unlinked
no new lookup can reach it, and any lookup already in progress holds the
mutex and has matched against a live pi before the free can run. No NULL
checks are needed on the lookup path.

Fixes: 9be9567a7c59 ("net: pse-pd: Add support for PSE PIs")
Signed-off-by: Carlo Szelinsky <redacted>
---
 drivers/net/pse-pd/pse_core.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 21ccb5146616..2a9a07dc8c48 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -1143,11 +1143,15 @@ void pse_controller_unregister(struct pse_controller_dev *pcdev)
 		disable_irq(pcdev->irq);
 	cancel_work_sync(&pcdev->ntf_work);
 	pse_flush_pw_ds(pcdev);
-	pse_release_pis(pcdev);
-	kfifo_free(&pcdev->ntf_fifo);
+	/* Unlink before freeing pcdev->pi: of_pse_control_get() walks the
+	 * list under pse_list_mutex and dereferences pcdev->pi[] via
+	 * of_pse_match_pi(), so a lookup must never reach a freed array.
+	 */
 	mutex_lock(&pse_list_mutex);
 	list_del(&pcdev->list);
 	mutex_unlock(&pse_list_mutex);
+	pse_release_pis(pcdev);
+	kfifo_free(&pcdev->ntf_fifo);
 }
 EXPORT_SYMBOL_GPL(pse_controller_unregister);
 
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help