From 5e00f0c778cc04fda52b3f6abebd4291aca19994 Mon Sep 17 00:00:00 2001 From: shichunma Date: Fri, 12 Jun 2026 10:57:53 +0800 Subject: [PATCH] net/devif: harden devif_conn_event() against list mutation devif_conn_event() saves list->nxtconn before invoking the current callback. If the callback mutates its callback list, the saved local successor may no longer match the post-callback list topology. Align devif_conn_event() with devif_dev_event(): protect the current callback with DEVIF_CB_DONT_FREE, refresh next after the callback returns, and defer freeing the current node until iteration is safe. Signed-off-by: shichunma --- net/devif/devif_callback.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/net/devif/devif_callback.c b/net/devif/devif_callback.c index 2f58ea6d32cda..d59ff7b9b895d 100644 --- a/net/devif/devif_callback.c +++ b/net/devif/devif_callback.c @@ -455,12 +455,26 @@ uint32_t devif_conn_event(FAR struct net_driver_s *dev, uint32_t flags, if (list->event != NULL && devif_event_trigger(flags, list->flags)) { + list->free_flags |= DEVIF_CB_DONT_FREE; + /* Yes.. perform the callback. Actions perform by the callback * may delete the current list entry or add a new list entry to * beginning of the list (which will be ignored on this pass) */ flags = list->event(dev, list->priv, flags); + list->free_flags &= ~DEVIF_CB_DONT_FREE; + + /* update the next callback to prevent previously recorded the + * next callback from being deleted + */ + + next = list->nxtconn; + if ((list->free_flags & DEVIF_CB_PEND_FREE) != 0) + { + list->free_flags &= ~DEVIF_CB_PEND_FREE; + devif_callback_free(dev, list, NULL, NULL); + } } /* Set up for the next time through the loop */