From 6f25d276fbf7336c90606f2347101e5d4c3f3441 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 5 Sep 2023 16:50:57 +0200 Subject: [PATCH] net: mgmt: Fix memory corruption in wait_on_iface The net_mgmt subsystem offers a function which waits (blocks) until a specified net event occurs. An event callback is pushed to the stack, then added to the net_mgmt_event_callback list. If the event occurs, the net_mgmt thread calls the callback and deletes the callback from the list. However, if the event does not occur within the timeout specified when invoking mgmt_event_wait_call() the function will return, corrupting the callback structure the stack is reused. This PR fixes the issue by deleting the callback before exiting in case the event does not occur. Signed-off-by: Bjarki Arge Andreasen --- subsys/net/ip/net_mgmt.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/subsys/net/ip/net_mgmt.c b/subsys/net/ip/net_mgmt.c index 94dac5ef6ef..4ae67a8aeda 100644 --- a/subsys/net/ip/net_mgmt.c +++ b/subsys/net/ip/net_mgmt.c @@ -236,29 +236,32 @@ static int mgmt_event_wait_call(struct net_if *iface, net_mgmt_add_event_callback(&sync); ret = k_sem_take(sync.sync_call, timeout); - if (ret == -EAGAIN) { - ret = -ETIMEDOUT; - } else { - if (!ret) { - if (raised_event) { - *raised_event = sync.raised_event; - } + if (ret < 0) { + if (ret == -EAGAIN) { + ret = -ETIMEDOUT; + } - if (event_iface) { - *event_iface = sync_data.iface; - } + net_mgmt_del_event_callback(&sync); + return ret; + } + + if (raised_event) { + *raised_event = sync.raised_event; + } + + if (event_iface) { + *event_iface = sync_data.iface; + } #ifdef CONFIG_NET_MGMT_EVENT_INFO - if (info) { - *info = sync.info; + if (info) { + *info = sync.info; - if (info_length) { - *info_length = sync.info_length; - } - } -#endif /* CONFIG_NET_MGMT_EVENT_INFO */ + if (info_length) { + *info_length = sync.info_length; } } +#endif /* CONFIG_NET_MGMT_EVENT_INFO */ return ret; }