This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 21def97623a net/devif: harden devif_conn_event() against list mutation
21def97623a is described below

commit 21def97623a4f45bfef0c976bf769be3581c5ed0
Author: shichunma <[email protected]>
AuthorDate: Fri Jun 12 10:57:53 2026 +0800

    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 <[email protected]>
---
 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 2f58ea6d32c..d59ff7b9b89 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 */

Reply via email to