[PATCH] MLD: Iterate per-link in wpa_clear_keys() for MLO group keys
Jouni Malinen
j at w1.fi
Fri Jul 31 11:33:45 PDT 2026
On Thu, May 07, 2026 at 02:11:44PM +0200, Louis Kotze wrote:
> When wpa_clear_keys() runs while wpa_s->valid_links is set, the
> DEL_KEY loop hardcodes link_id=-1. The kernel cfg80211 validator
> nl80211_validate_key_link_id() (introduced in commit e7a7b84e3317
> ('wifi: cfg80211: Add link_id parameter to various key operations
> for MLO'), Linux v6.1+) rejects DEL_KEY for group keys when
> wdev->valid_links != 0 and link_id == -1. The DEL_KEYs fail (one
> per protected key type: GTK, IGTK, BIGTK), leaving stale per-link
> keys in the driver, and the next association is rejected by the
> AP with reason 9 (STA_REQ_ASSOC_WITHOUT_AUTH). wpa_supplicant
> retries until the SSID is temporarily disabled, then loops on
> backoff.
That's only the case for the time when the ML association continues to
exist. Once it it is removed (through disassociation or
deauthentication), at least the current Linux kernel implementation (and
anything supporting MLO, I'd hope) ends up deleting all the related keys
automatically.
> The trigger path is PMKSA-cached reauth on a multi-link AP:
> sme_send_authentication() calls wpa_clear_keys() before sending
> the fast-reauth association. valid_links is still set from the
> prior association at that moment, so every group-key DEL_KEY hits
> the validator and fails.
I don't think this is in any way specific to PMKSA caching. Since there
was no debug log from wpa_supplicant here or in the referenced bugzilla
entry, I tested this with the control interface REASSOCIATE command.
> Iterate over wpa_s->valid_links and pass the corresponding
> link_id for each active link's group-key DEL_KEY. The non-MLO
> path is unchanged.
This "breaks" the disconnected state in the sense of making the debug
log confusing with the kernel rejecting all DEL_KEYs since they have a
link ID specified when the kernel does not anymore have the keys (due to
that disconnection having deleted them).
I could not fully t confirm that this addresses the case you are
describing, but I think it should, so I applied a slightly different
version with the condition for the new behavior included connection
state being fully associated:
https://git.w1.fi/cgit/hostap/commit/?id=9a3b596e0e5c8b66779a501ec36357f970dd577c
--
Jouni Malinen PGP id EFC895FA
More information about the Hostap
mailing list