mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 23:09:34 +01:00
netdev: use l_idle_create for disconnect idle
The chances were extremely low, but using l_idle_oneshot could end up causing a invalid memory access if the netdev went down while waiting for the disconnect idle callback. Instead netdev can keep track of the idle with l_idle_create and remove it if the netdev goes down prior to the idle callback.
This commit is contained in:
parent
51fc2453ba
commit
6c9f72380d
16
src/netdev.c
16
src/netdev.c
@ -148,6 +148,8 @@ struct netdev {
|
|||||||
void *get_station_data;
|
void *get_station_data;
|
||||||
netdev_destroy_func_t get_station_destroy;
|
netdev_destroy_func_t get_station_destroy;
|
||||||
|
|
||||||
|
struct l_idle *disconnect_idle;
|
||||||
|
|
||||||
struct watchlist station_watches;
|
struct watchlist station_watches;
|
||||||
|
|
||||||
struct l_io *pae_io; /* for drivers without EAPoL over NL80211 */
|
struct l_io *pae_io; /* for drivers without EAPoL over NL80211 */
|
||||||
@ -811,6 +813,11 @@ static void netdev_free(void *data)
|
|||||||
if (netdev->fw_roam_bss)
|
if (netdev->fw_roam_bss)
|
||||||
scan_bss_free(netdev->fw_roam_bss);
|
scan_bss_free(netdev->fw_roam_bss);
|
||||||
|
|
||||||
|
if (netdev->disconnect_idle) {
|
||||||
|
l_idle_remove(netdev->disconnect_idle);
|
||||||
|
netdev->disconnect_idle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (netdev->events_ready)
|
if (netdev->events_ready)
|
||||||
WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
|
WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
|
||||||
netdev, NETDEV_WATCH_EVENT_DEL);
|
netdev, NETDEV_WATCH_EVENT_DEL);
|
||||||
@ -3182,10 +3189,13 @@ build_cmd_connect:
|
|||||||
event_filter, cb, user_data);
|
event_filter, cb, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconnect_idle(void *user_data)
|
static void disconnect_idle(struct l_idle *idle, void *user_data)
|
||||||
{
|
{
|
||||||
struct netdev *netdev = user_data;
|
struct netdev *netdev = user_data;
|
||||||
|
|
||||||
|
l_idle_remove(idle);
|
||||||
|
netdev->disconnect_idle = NULL;
|
||||||
|
|
||||||
netdev->disconnect_cb(netdev, true, netdev->user_data);
|
netdev->disconnect_cb(netdev, true, netdev->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3249,8 +3259,8 @@ int netdev_disconnect(struct netdev *netdev,
|
|||||||
} else if (cb) {
|
} else if (cb) {
|
||||||
netdev->disconnect_cb = cb;
|
netdev->disconnect_cb = cb;
|
||||||
netdev->user_data = user_data;
|
netdev->user_data = user_data;
|
||||||
|
netdev->disconnect_idle = l_idle_create(disconnect_idle,
|
||||||
l_idle_oneshot(disconnect_idle, netdev, NULL);
|
netdev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user