[PATCH net v2 09/14] net: pse-pd: unregister from the controller list before freeing PI data

From: Carlo Szelinsky

Date: Tue Oct 20 2026 - 13:19:53 EST


pse_controller_unregister() frees the PI array while the controller is
still on pse_controller_list, and only removes it from the list
afterwards. of_pse_control_get() walks that list under pse_list_mutex
and reads pcdev->pi[i].np in of_pse_match_pi(). A consumer that probes
at that moment can read the freed PI array.

Remove the controller from the list first, before the worker is
drained, the power domains are flushed and the PI array is freed. Both
sides take pse_list_mutex, so once the controller is off the list, no
new lookup can find it, and a lookup that is already running finishes
before the PI array is freed.

Found by code inspection. Not reproduced.

Fixes: 9be9567a7c59 ("net: pse-pd: Add support for PSE PIs")
Reviewed-by: Kory Maincent <kory.maincent@xxxxxxxxxxx>
Signed-off-by: Carlo Szelinsky <github@xxxxxxxxxxxx>
---
drivers/net/pse-pd/pse_core.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 21280479312e..f266cc24f6a2 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -1143,13 +1143,17 @@ void pse_controller_unregister(struct pse_controller_dev *pcdev)
*/
if (pcdev->irq)
disable_irq(pcdev->irq);
+ /* Unlink before tearing down: of_pse_control_get() walks the list
+ * and reads pcdev->pi[], and must not hand out a new control for a
+ * controller that is going away.
+ */
+ mutex_lock(&pse_list_mutex);
+ list_del(&pcdev->list);
+ mutex_unlock(&pse_list_mutex);
cancel_work_sync(&pcdev->ntf_work);
pse_flush_pw_ds(pcdev);
pse_release_pis(pcdev);
kfifo_free(&pcdev->ntf_fifo);
- mutex_lock(&pse_list_mutex);
- list_del(&pcdev->list);
- mutex_unlock(&pse_list_mutex);
}
EXPORT_SYMBOL_GPL(pse_controller_unregister);

--
2.43.0