mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 06:29:23 +01:00
station/network: avoid use-after-free
ConnectHiddenNetwork creates a temporary network object and initiates a
connection with it. If the connection fails (due to an incorrect
passphrase or other reasons), then this temporary object is destroyed.
Delay its destruction until network_disconnected() since
network_connect_failed is called too early. Also, re-order the sequence
in station_reset_connection_state() in order to avoid using the network
object after it has been freed by network_disconnected().
Fixes: 85d9d6461f
("network: Hide hidden networks on connection error")
This commit is contained in:
parent
867c68c05b
commit
8a877d8692
@ -198,6 +198,9 @@ void network_disconnected(struct network *network)
|
||||
network_settings_close(network);
|
||||
|
||||
l_queue_clear(network->blacklist, NULL);
|
||||
|
||||
if (network->provisioning_hidden)
|
||||
station_hide_network(network->station, network);
|
||||
}
|
||||
|
||||
/* First 64 entries calculated by 1 / pow(n, 0.3) for n >= 1 */
|
||||
@ -983,9 +986,6 @@ void network_connect_failed(struct network *network, bool in_handshake)
|
||||
|
||||
l_queue_destroy(network->secrets, eap_secret_info_free);
|
||||
network->secrets = NULL;
|
||||
|
||||
if (network->provisioning_hidden)
|
||||
station_hide_network(network->station, network);
|
||||
}
|
||||
|
||||
static bool hotspot_info_matches(struct network *network,
|
||||
|
@ -1616,12 +1616,6 @@ static void station_reset_connection_state(struct station *station)
|
||||
if (!network)
|
||||
return;
|
||||
|
||||
if (station->state == STATION_STATE_CONNECTED ||
|
||||
station->state == STATION_STATE_CONNECTING ||
|
||||
station->state == STATION_STATE_CONNECTING_AUTO ||
|
||||
station->state == STATION_STATE_ROAMING)
|
||||
network_disconnected(network);
|
||||
|
||||
station_roam_state_clear(station);
|
||||
|
||||
/* Refresh the ordered network list */
|
||||
@ -1639,6 +1633,17 @@ static void station_reset_connection_state(struct station *station)
|
||||
IWD_NETWORK_INTERFACE, "Connected");
|
||||
l_dbus_object_remove_interface(dbus, netdev_get_path(station->netdev),
|
||||
IWD_STATION_DIAGNOSTIC_INTERFACE);
|
||||
|
||||
/*
|
||||
* Perform this step last since calling network_disconnected() might
|
||||
* result in the removal of the network (for example if provisioning
|
||||
* a new hidden network fails with an incorrect pasword).
|
||||
*/
|
||||
if (station->state == STATION_STATE_CONNECTED ||
|
||||
station->state == STATION_STATE_CONNECTING ||
|
||||
station->state == STATION_STATE_CONNECTING_AUTO ||
|
||||
station->state == STATION_STATE_ROAMING)
|
||||
network_disconnected(network);
|
||||
}
|
||||
|
||||
static void station_disassociated(struct station *station)
|
||||
|
Loading…
Reference in New Issue
Block a user