mirror of
				https://git.kernel.org/pub/scm/network/wireless/iwd.git
				synced 2025-11-04 08:57:29 +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: 85d9d6461f1f ("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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user