mirror of
				https://git.kernel.org/pub/scm/network/wireless/iwd.git
				synced 2025-10-31 13:17:25 +01:00 
			
		
		
		
	scan: Don't crash on scan_cancel
If scan_cancel is called on a scan_request that is 'finished' but with the GET_SCAN command still in flight, it will trigger a crash as follows: Received Deauthentication event, reason: 2, from_ap: true src/station.c:station_disconnect_event() 11 src/station.c:station_disassociated() 11 src/station.c:station_reset_connection_state() 11 src/station.c:station_roam_state_clear() 11 src/scan.c:scan_cancel() Trying to cancel scan id 6 for wdev 200000002 src/scan.c:scan_cancel() Scan is at the top of the queue, but not triggered src/scan.c:get_scan_done() get_scan_done Aborting (signal 11) [/home/denkenz/iwd-master/src/iwd] ++++++++ backtrace ++++++++ #0 0x7f9871aef3f0 in /lib64/libc.so.6 #1 0x41f470 in station_roam_scan_notify() at /home/denkenz/iwd-master/src/station.c:2285 #2 0x43936a in scan_finished() at /home/denkenz/iwd-master/src/scan.c:1709 #3 0x439495 in get_scan_done() at /home/denkenz/iwd-master/src/scan.c:1739 #4 0x4bdef5 in destroy_request() at /home/denkenz/iwd-master/ell/genl.c:676 #5 0x4c070b in l_genl_family_cancel() at /home/denkenz/iwd-master/ell/genl.c:1960 #6 0x437069 in scan_cancel() at /home/denkenz/iwd-master/src/scan.c:842 #7 0x41dc2e in station_roam_state_clear() at /home/denkenz/iwd-master/src/station.c:1594 #8 0x41dd2b in station_reset_connection_state() at /home/denkenz/iwd-master/src/station.c:1619 #9 0x41dea4 in station_disassociated() at /home/denkenz/iwd-master/src/station.c:1644 The happens because get_scan_done callback is still called as a result of l_genl_cancel. Add a re-entrancy guard in the form of 'canceled' variable in struct scan_request. If set, get_scan_done will skip invoking scan_finished. It isn't clear what 'l_queue_peek_head() == results->sr' check was trying to accomplish. If GET_SCAN dump was scheduled, then it should be reported. Drop it.
This commit is contained in:
		
							parent
							
								
									e1593df4bd
								
							
						
					
					
						commit
						af375a1cde
					
				| @ -79,6 +79,7 @@ struct scan_request { | ||||
| 	scan_notify_func_t callback; | ||||
| 	void *userdata; | ||||
| 	scan_destroy_func_t destroy; | ||||
| 	bool canceled : 1; /* Is scan_cancel being called on this request? */ | ||||
| 	bool passive:1; /* Active or Passive scan? */ | ||||
| 	struct l_queue *cmds; | ||||
| 	/* The time the current scan was started. Reported in TRIGGER_SCAN */ | ||||
| @ -833,6 +834,9 @@ bool scan_cancel(uint64_t wdev_id, uint32_t id) | ||||
| 	if (sr == l_queue_peek_head(sc->requests)) { | ||||
| 		l_debug("Scan is at the top of the queue, but not triggered"); | ||||
| 
 | ||||
| 		/* l_genl_family_cancel will trigger destroy callbacks */ | ||||
| 		sr->canceled = true; | ||||
| 
 | ||||
| 		if (sc->start_cmd_id) | ||||
| 			l_genl_family_cancel(nl80211, sc->start_cmd_id); | ||||
| 
 | ||||
| @ -1735,7 +1739,7 @@ static void get_scan_done(void *user) | ||||
| 
 | ||||
| 	sc->get_scan_cmd_id = 0; | ||||
| 
 | ||||
| 	if (!results->sr || l_queue_peek_head(sc->requests) == results->sr) | ||||
| 	if (!results->sr || !results->sr->canceled) | ||||
| 		scan_finished(sc, 0, results->bss_list, | ||||
| 						results->freqs, results->sr); | ||||
| 	else | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Denis Kenzior
						Denis Kenzior