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 <shichunma@bestechnic.com>
This commit is contained in:
shichunma 2026-06-12 10:57:53 +08:00 committed by Alan C. Assis
parent b840bf6552
commit 21def97623

View file

@ -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 */