From 16f1b8b72ba46415dbd4383af2685a75640e07e8 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 27 Aug 2025 12:58:24 +0300 Subject: [PATCH] GAS: Prefer unique dialog token value across all pending queries Previously, the dialog token for a new GAS query was selected in a manner that would be random and unique for the specific peer. However, with the introduction of support for AP MLDs, multiple different addresses could have ended up using the same dialog token value for the same peer. Make duplicate dialog token uses for AP MLDs less likely by first trying to find a random dialog token value that is not used in any pending GAS query for any peer. Only if that does not succeed, fall back to unique value for the specific peer address to maintain previous behavior. Signed-off-by: Jouni Malinen --- wpa_supplicant/gas_query.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c index b3ebac168..63424505f 100644 --- a/wpa_supplicant/gas_query.c +++ b/wpa_supplicant/gas_query.c @@ -685,7 +685,7 @@ static int gas_query_dialog_token_available(struct gas_query *gas, { struct gas_query_pending *q; dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) { - if (ether_addr_equal(dst, q->addr) && + if ((!dst || ether_addr_equal(dst, q->addr)) && dialog_token == q->dialog_token) return 0; } @@ -756,6 +756,18 @@ static int gas_query_new_dialog_token(struct gas_query *gas, const u8 *dst) * token by checking random values. Use a limit on the number of * iterations to handle the unexpected case of large number of pending * queries cleanly. */ + for (i = 0; i < 256; i++) { + /* Get a random number and check if it is not used in any + * pending entry for any peer. */ + if (os_get_random(&dialog_token, sizeof(dialog_token)) < 0) + break; + if (gas_query_dialog_token_available(gas, NULL, dialog_token)) + return dialog_token; + } + + /* In the highly unlikely case there were so many pending queries that + * no available unused dialog token was available. Try to find one that + * is unique for this specific peer. */ for (i = 0; i < 256; i++) { /* Get a random number and check if the slot is available */ if (os_get_random(&dialog_token, sizeof(dialog_token)) < 0) -- 2.47.3