mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 14:49:24 +01:00
frame-xchg: Fix group removal inside frame callback
When a frame registered in a given group Id triggers a callback and that callback ends up calling frame_watch_group_remove for that group Id, that call will happen inside WATCHLIST_NOTIFY_MATCHES and will free the memory used by the watchlist. watchlist.h has protection against the watchlist being "destroyed" inside WATCHLIST_NOTIFY_MATCHES, but not against its memory being freed -- the memory where it stores the in_notify and destroy_pending flags. Free the group immediately after WATCHLIST_NOTIFY_MATCHES to avoid reads/writes to those flags triggering valgrind warnings.
This commit is contained in:
parent
1f4b32ff53
commit
5600c736b8
@ -231,6 +231,10 @@ static void frame_watch_unicast_notify(struct l_genl_msg *msg, void *user_data)
|
|||||||
WATCHLIST_NOTIFY_MATCHES(&group->watches, frame_watch_match_prefix,
|
WATCHLIST_NOTIFY_MATCHES(&group->watches, frame_watch_match_prefix,
|
||||||
&info, frame_watch_cb_t, mpdu,
|
&info, frame_watch_cb_t, mpdu,
|
||||||
info.body, info.body_len, rssi);
|
info.body, info.body_len, rssi);
|
||||||
|
|
||||||
|
/* Has frame_watch_group_destroy been called inside a frame CB? */
|
||||||
|
if (group->watches.pending_destroy)
|
||||||
|
l_free(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void frame_watch_group_destroy(void *data)
|
static void frame_watch_group_destroy(void *data)
|
||||||
@ -244,7 +248,16 @@ static void frame_watch_group_destroy(void *data)
|
|||||||
l_io_destroy(group->io);
|
l_io_destroy(group->io);
|
||||||
l_queue_destroy(group->write_queue,
|
l_queue_destroy(group->write_queue,
|
||||||
(l_queue_destroy_func_t) l_genl_msg_unref);
|
(l_queue_destroy_func_t) l_genl_msg_unref);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may be inside a frame notification but even then use
|
||||||
|
* watchlist_destroy to prevent any more notifications from
|
||||||
|
* being dispatched.
|
||||||
|
*/
|
||||||
watchlist_destroy(&group->watches);
|
watchlist_destroy(&group->watches);
|
||||||
|
if (group->watches.in_notify)
|
||||||
|
return;
|
||||||
|
|
||||||
l_free(group);
|
l_free(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user