D-Bus: Share 'remove all networks' with CLI
The D-Bus implementation of RemoveAllNetworks differs wildly from the CLI implementation. Let's share the implementations. This resolves use-after-free bugs I noticed, where we continue to use the 'wpa_s->current_ssid' wpa_ssid object after freeing it, because we didn't bother to disconnect from (and set to NULL) current_ssid before freeing it. Signed-off-by: Brian Norris <briannorris@chromium.org>
This commit is contained in:
parent
07aac648a1
commit
4b96fafcd8
4 changed files with 49 additions and 50 deletions
|
@ -3480,38 +3480,12 @@ static int wpa_supplicant_ctrl_iface_remove_network(
|
||||||
struct wpa_supplicant *wpa_s, char *cmd)
|
struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
struct wpa_ssid *ssid;
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* cmd: "<network id>" or "all" */
|
/* cmd: "<network id>" or "all" */
|
||||||
if (os_strcmp(cmd, "all") == 0) {
|
if (os_strcmp(cmd, "all") == 0) {
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
|
||||||
if (wpa_s->sched_scanning)
|
return wpa_supplicant_remove_all_networks(wpa_s);
|
||||||
wpa_supplicant_cancel_sched_scan(wpa_s);
|
|
||||||
|
|
||||||
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
|
||||||
if (wpa_s->current_ssid) {
|
|
||||||
#ifdef CONFIG_SME
|
|
||||||
wpa_s->sme.prev_bssid_set = 0;
|
|
||||||
#endif /* CONFIG_SME */
|
|
||||||
wpa_sm_set_config(wpa_s->wpa, NULL);
|
|
||||||
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
|
||||||
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
|
|
||||||
wpa_s->own_disconnect_req = 1;
|
|
||||||
wpa_supplicant_deauthenticate(
|
|
||||||
wpa_s, WLAN_REASON_DEAUTH_LEAVING);
|
|
||||||
}
|
|
||||||
ssid = wpa_s->conf->ssid;
|
|
||||||
while (ssid) {
|
|
||||||
struct wpa_ssid *remove_ssid = ssid;
|
|
||||||
id = ssid->id;
|
|
||||||
ssid = ssid->next;
|
|
||||||
if (wpa_s->last_ssid == remove_ssid)
|
|
||||||
wpa_s->last_ssid = NULL;
|
|
||||||
wpas_notify_network_removed(wpa_s, remove_ssid);
|
|
||||||
wpa_config_remove_network(wpa_s->conf, id);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id = atoi(cmd);
|
id = atoi(cmd);
|
||||||
|
|
|
@ -1817,25 +1817,6 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void remove_network(void *arg, struct wpa_ssid *ssid)
|
|
||||||
{
|
|
||||||
struct wpa_supplicant *wpa_s = arg;
|
|
||||||
|
|
||||||
wpas_notify_network_removed(wpa_s, ssid);
|
|
||||||
|
|
||||||
if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) {
|
|
||||||
wpa_printf(MSG_ERROR,
|
|
||||||
"%s[dbus]: error occurred when removing network %d",
|
|
||||||
__func__, ssid->id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssid == wpa_s->current_ssid)
|
|
||||||
wpa_supplicant_deauthenticate(wpa_s,
|
|
||||||
WLAN_REASON_DEAUTH_LEAVING);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wpas_dbus_handler_remove_all_networks - Remove all configured networks
|
* wpas_dbus_handler_remove_all_networks - Remove all configured networks
|
||||||
* @message: Pointer to incoming dbus message
|
* @message: Pointer to incoming dbus message
|
||||||
|
@ -1847,11 +1828,8 @@ static void remove_network(void *arg, struct wpa_ssid *ssid)
|
||||||
DBusMessage * wpas_dbus_handler_remove_all_networks(
|
DBusMessage * wpas_dbus_handler_remove_all_networks(
|
||||||
DBusMessage *message, struct wpa_supplicant *wpa_s)
|
DBusMessage *message, struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
if (wpa_s->sched_scanning)
|
|
||||||
wpa_supplicant_cancel_sched_scan(wpa_s);
|
|
||||||
|
|
||||||
/* NB: could check for failure and return an error */
|
/* NB: could check for failure and return an error */
|
||||||
wpa_config_foreach_network(wpa_s->conf, remove_network, wpa_s);
|
wpa_supplicant_remove_all_networks(wpa_s);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4122,6 +4122,52 @@ int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpa_supplicant_remove_all_networks - Remove all configured networks
|
||||||
|
* @wpa_s: wpa_supplicant structure for a network interface
|
||||||
|
* Returns: 0 on success (errors are currently ignored)
|
||||||
|
*
|
||||||
|
* This function performs the following operations:
|
||||||
|
* 1. Remove all networks.
|
||||||
|
* 2. Send network removal notifications.
|
||||||
|
* 3. Update internal state machines.
|
||||||
|
* 4. Stop any running sched scans.
|
||||||
|
*/
|
||||||
|
int wpa_supplicant_remove_all_networks(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
struct wpa_ssid *ssid;
|
||||||
|
|
||||||
|
if (wpa_s->sched_scanning)
|
||||||
|
wpa_supplicant_cancel_sched_scan(wpa_s);
|
||||||
|
|
||||||
|
eapol_sm_invalidate_cached_session(wpa_s->eapol);
|
||||||
|
if (wpa_s->current_ssid) {
|
||||||
|
#ifdef CONFIG_SME
|
||||||
|
wpa_s->sme.prev_bssid_set = 0;
|
||||||
|
#endif /* CONFIG_SME */
|
||||||
|
wpa_sm_set_config(wpa_s->wpa, NULL);
|
||||||
|
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
||||||
|
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
|
||||||
|
wpa_s->own_disconnect_req = 1;
|
||||||
|
wpa_supplicant_deauthenticate(
|
||||||
|
wpa_s, WLAN_REASON_DEAUTH_LEAVING);
|
||||||
|
}
|
||||||
|
ssid = wpa_s->conf->ssid;
|
||||||
|
while (ssid) {
|
||||||
|
struct wpa_ssid *remove_ssid = ssid;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
id = ssid->id;
|
||||||
|
ssid = ssid->next;
|
||||||
|
if (wpa_s->last_ssid == remove_ssid)
|
||||||
|
wpa_s->last_ssid = NULL;
|
||||||
|
wpas_notify_network_removed(wpa_s, remove_ssid);
|
||||||
|
wpa_config_remove_network(wpa_s->conf, id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wpa_supplicant_enable_network - Mark a configured network as enabled
|
* wpa_supplicant_enable_network - Mark a configured network as enabled
|
||||||
* @wpa_s: wpa_supplicant structure for a network interface
|
* @wpa_s: wpa_supplicant structure for a network interface
|
||||||
|
|
|
@ -1381,6 +1381,7 @@ void wpa_supplicant_reconnect(struct wpa_supplicant *wpa_s);
|
||||||
|
|
||||||
struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s);
|
struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s);
|
||||||
int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id);
|
int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id);
|
||||||
|
int wpa_supplicant_remove_all_networks(struct wpa_supplicant *wpa_s);
|
||||||
void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
|
void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid);
|
struct wpa_ssid *ssid);
|
||||||
void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
|
void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
|
||||||
|
|
Loading…
Reference in a new issue