]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
GAS: Do not select pending query that has not yet been sent
authorJouni Malinen <jouni.malinen@oss.qualcomm.com>
Thu, 28 Aug 2025 08:29:24 +0000 (11:29 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 28 Aug 2025 08:29:24 +0000 (11:29 +0300)
An unexpected GAS response for a query that was scheduled to be sent,
but not yet actually transmitted, could result in unexpected behavior.
This could end up selecting the pending query for which the radio work
had not yet been started when processing the received frame and that
could result in freeing the pending query but not being able to
terminate the radio work that still has a reference to the pending
query.

Do not allow a pending GAS query to match a received frame if that query
has not yet been transmitted to avoid this corner case.

Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
wpa_supplicant/gas_query.c

index 63424505f32e35a57f5af4625b59b6f40343c68d..f437892966ed28ee446eac5911eaa5f413f46dc6 100644 (file)
@@ -46,6 +46,7 @@ struct gas_query_pending {
        unsigned int retry:1;
        unsigned int wildcard_bssid:1;
        unsigned int maintain_addr:1;
+       unsigned int sent:1;
        int freq;
        u16 status_code;
        struct wpabuf *req;
@@ -209,6 +210,8 @@ gas_query_get_pending(struct gas_query *gas, const u8 *addr, u8 dialog_token)
         * AP MLD MAC address here, a same dialog token value might end up
         * being pending and matching the same query. */
        dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) {
+               if (!q->sent)
+                       continue;
                if ((ether_addr_equal(q->addr, addr) &&
                     q->dialog_token == dialog_token) ||
                    (wpa_s->valid_links &&
@@ -327,8 +330,10 @@ static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
                                     wpabuf_len(req), wait_time,
                                     gas_query_tx_status, 0);
 
-       if (res == 0)
+       if (res == 0) {
+               query->sent = 1;
                query->offchannel_tx_started = 1;
+       }
        return res;
 }