mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-26 10:39: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);
|
network_settings_close(network);
|
||||||
|
|
||||||
l_queue_clear(network->blacklist, NULL);
|
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 */
|
/* 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);
|
l_queue_destroy(network->secrets, eap_secret_info_free);
|
||||||
network->secrets = NULL;
|
network->secrets = NULL;
|
||||||
|
|
||||||
if (network->provisioning_hidden)
|
|
||||||
station_hide_network(network->station, network);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hotspot_info_matches(struct network *network,
|
static bool hotspot_info_matches(struct network *network,
|
||||||
|
@ -1616,12 +1616,6 @@ static void station_reset_connection_state(struct station *station)
|
|||||||
if (!network)
|
if (!network)
|
||||||
return;
|
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);
|
station_roam_state_clear(station);
|
||||||
|
|
||||||
/* Refresh the ordered network list */
|
/* Refresh the ordered network list */
|
||||||
@ -1639,6 +1633,17 @@ static void station_reset_connection_state(struct station *station)
|
|||||||
IWD_NETWORK_INTERFACE, "Connected");
|
IWD_NETWORK_INTERFACE, "Connected");
|
||||||
l_dbus_object_remove_interface(dbus, netdev_get_path(station->netdev),
|
l_dbus_object_remove_interface(dbus, netdev_get_path(station->netdev),
|
||||||
IWD_STATION_DIAGNOSTIC_INTERFACE);
|
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)
|
static void station_disassociated(struct station *station)
|
||||||
|
Loading…
Reference in New Issue
Block a user