From 8db4d9272a84bbe5fbb0bfbfa7341408f191b74c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Mon, 8 Jun 2020 10:42:07 +0200 Subject: [PATCH] scan: refactor start_next_scan_request to not send duplicate requests If start_scan_next_request() is called while a scan request (NL80211_CMD_TRIGGER_SCAN) is still running, the same scan request will be sent again. Add a check in the function to avoid sending a request if one is already in progress. For consistency, check also that scan results are not being requested (NL80211_CMD_GET_SCAN), before trying to send the next scan request. Finally, remove similar checks at start_next_scan_request() callsites to simplify the code. This also fixes a crash that occurs if the following conditions are met: - the duplicated request is the only request in the scan request queue, and - both scan requests fail with an error not EBUSY. In this case, the first callback to scan_request_triggered() will delete the request from the scan request queue. The second callback will find an empty queue and consequently pass a NULL scan_request pointer to scan_request_failed(), causing a segmentation fault. --- src/scan.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/scan.c b/src/scan.c index 8fc1f026..83804e57 100644 --- a/src/scan.c +++ b/src/scan.c @@ -842,6 +842,9 @@ static bool start_next_scan_request(struct scan_context *sc) if (sc->state != SCAN_STATE_NOT_RUNNING) return true; + if (sc->start_cmd_id || sc->get_scan_cmd_id) + return true; + while (sr) { if (!scan_request_send_trigger(sc, sr)) return true; @@ -1668,7 +1671,7 @@ static void scan_notify(struct l_genl_msg *msg, void *user_data) /* An external scan may have flushed our results */ if (sc->started && scan_parse_flush_flag_from_msg(msg)) scan_finished(sc, -EAGAIN, NULL, sr); - else if (sr && !sc->start_cmd_id) + else send_next = true; sr = NULL; @@ -1719,7 +1722,7 @@ static void scan_notify(struct l_genl_msg *msg, void *user_data) sc->triggered = false; scan_finished(sc, -ECANCELED, NULL, sr); - } else if (sr && !sc->start_cmd_id && !sc->get_scan_cmd_id) { + } else { /* * If this was an external scan that got aborted * we may be able to now queue our own scan although