mirror of
				https://git.kernel.org/pub/scm/network/wireless/iwd.git
				synced 2025-10-31 04:57:25 +01:00 
			
		
		
		
	network: Fix a bunch of double-frees
Missing secrets are freed by eap_send_agent_req() even in case of failure, so it was erroneous to try to free them on error. ==1048== Invalid read of size 8 ==1048== at 0x1603EC: l_queue_clear (queue.c:101) ==1048== by 0x1603B8: l_queue_destroy (queue.c:82) ==1048== by 0x135328: network_connect_8021x (network.c:943) ==1048== by 0x1354C4: network_connect (network.c:987) ==1048== by 0x178DD2: _dbus_object_tree_dispatch (dbus-service.c:1690) ==1048== by 0x16D32A: message_read_handler (dbus.c:285) ==1048== by 0x166EC3: io_callback (io.c:123) ==1048== by 0x165A1A: l_main_iterate (main.c:376) ==1048== by 0x165B58: l_main_run (main.c:423) ==1048== by 0x1102DA: main (main.c:458) ==1048== Address 0x5461850 is 0 bytes inside a block of size 24 free'd ==1048== at 0x4C2C13B: free (vg_replace_malloc.c:530) ==1048== by 0x15ED03: l_free (util.c:136) ==1048== by 0x1603C4: l_queue_destroy (queue.c:83) ==1048== by 0x134BD5: eap_secret_request_free (network.c:719) ==1048== by 0x134EF9: eap_send_agent_req (network.c:817) ==1048== by 0x1352F7: network_connect_8021x (network.c:936) ==1048== by 0x1354C4: network_connect (network.c:987) ==1048== by 0x178DD2: _dbus_object_tree_dispatch (dbus-service.c:1690) ==1048== by 0x16D32A: message_read_handler (dbus.c:285) ==1048== by 0x166EC3: io_callback (io.c:123) ==1048== by 0x165A1A: l_main_iterate (main.c:376) ==1048== by 0x165B58: l_main_run (main.c:423)
This commit is contained in:
		
							parent
							
								
									75b492eacc
								
							
						
					
					
						commit
						250568025c
					
				
							
								
								
									
										49
									
								
								src/eap.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								src/eap.c
									
									
									
									
									
								
							| @ -414,12 +414,30 @@ void eap_secret_info_free(void *data) | ||||
| 	l_free(info); | ||||
| } | ||||
| 
 | ||||
| static int eap_setting_exists(struct l_settings *settings, | ||||
| 				const char *setting, | ||||
| 				struct l_queue *secrets, | ||||
| 				struct l_queue *missing) | ||||
| { | ||||
| 	if (l_settings_get_value(settings, "Security", setting)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (l_queue_find(secrets, eap_secret_info_match, setting)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (l_queue_find(missing, eap_secret_info_match, setting)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return -ENOENT; | ||||
| } | ||||
| 
 | ||||
| int eap_check_settings(struct l_settings *settings, struct l_queue *secrets, | ||||
| 			const char *prefix, bool set_key_material, | ||||
| 			struct l_queue **out_missing) | ||||
| { | ||||
| 	char setting[64]; | ||||
| 	const char *method_name; | ||||
| 	struct l_queue *missing = NULL; | ||||
| 	const struct l_queue_entry *entry; | ||||
| 	struct eap_method *method; | ||||
| 	int ret = 0; | ||||
| @ -429,7 +447,6 @@ int eap_check_settings(struct l_settings *settings, struct l_queue *secrets, | ||||
| 
 | ||||
| 	if (!method_name) { | ||||
| 		l_error("Property %s missing", setting); | ||||
| 
 | ||||
| 		return -ENOENT; | ||||
| 	} | ||||
| 
 | ||||
| @ -443,7 +460,6 @@ int eap_check_settings(struct l_settings *settings, struct l_queue *secrets, | ||||
| 
 | ||||
| 	if (!entry) { | ||||
| 		l_error("EAP method \"%s\" unsupported", method_name); | ||||
| 
 | ||||
| 		return -ENOTSUP; | ||||
| 	} | ||||
| 
 | ||||
| @ -451,36 +467,37 @@ int eap_check_settings(struct l_settings *settings, struct l_queue *secrets, | ||||
| 	if (set_key_material && !method->exports_msk) { | ||||
| 		l_error("EAP method \"%s\" doesn't export key material", | ||||
| 				method_name); | ||||
| 
 | ||||
| 		return -ENOTSUP; | ||||
| 	} | ||||
| 
 | ||||
| 	if (method->check_settings) | ||||
| 		ret = method->check_settings(settings, secrets, | ||||
| 						prefix, out_missing); | ||||
| 						prefix, &missing); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 		goto error; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Methods that provide the get_identity callback are responsible | ||||
| 	 * for ensuring, inside check_settings(), that they have enough data | ||||
| 	 * to return the identity after load_settings(). | ||||
| 	 */ | ||||
| 	if (method->get_identity) | ||||
| 		return 0; | ||||
| 	if (!method->get_identity) { | ||||
| 		snprintf(setting, sizeof(setting), "%sIdentity", prefix); | ||||
| 
 | ||||
| 	snprintf(setting, sizeof(setting), "%sIdentity", prefix); | ||||
| 	if (!l_settings_get_value(settings, "Security", setting) && | ||||
| 			!l_queue_find(secrets, eap_secret_info_match, | ||||
| 					setting) && | ||||
| 			!l_queue_find(*out_missing, eap_secret_info_match, | ||||
| 					setting)) { | ||||
| 		l_error("Property %s is missing", setting); | ||||
| 
 | ||||
| 		return -ENOENT; | ||||
| 		ret = eap_setting_exists(settings, setting, secrets, missing); | ||||
| 		if (ret < 0) { | ||||
| 			l_error("Property %s is missing", setting); | ||||
| 			ret = -ENOENT; | ||||
| 			goto error; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	*out_missing = missing; | ||||
| 	return 0; | ||||
| 
 | ||||
| error: | ||||
| 	l_queue_destroy(missing, eap_secret_info_free); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| bool eap_load_settings(struct eap_state *eap, struct l_settings *settings, | ||||
|  | ||||
| @ -940,8 +940,6 @@ static struct l_dbus_message *network_connect_8021x(struct network *network, | ||||
| 	reply = dbus_error_no_agent(message); | ||||
| 
 | ||||
| error: | ||||
| 	l_queue_destroy(missing_secrets, eap_secret_info_free); | ||||
| 
 | ||||
| 	network_settings_close(network); | ||||
| 
 | ||||
| 	l_queue_destroy(network->secrets, eap_secret_info_free); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Denis Kenzior
						Denis Kenzior