From: Suchir Kavi <suchirkavi@gmail.com>
To: iwd@lists.linux.dev
Subject: [PATCH 0/3] Fix two station roaming crashes
Date: Wed, 15 Jul 2026 19:34:41 -0700 [thread overview]
Message-ID: <20260716023444.3512595-1-suchirkavi@gmail.com> (raw)
We run iwd on a large number of embedded aarch64 Linux devices
(WPA3-SAE, frequently multi-AP mesh networks) and root-caused two
recurring segfaults from coredumps and journals. Both are present in
current master by inspection, and together they account for the
majority of the iwd crashes we see on current builds. Heads up that
this cover letter and patchset are primarily AI-generated (Fable) but
reviewed by me.
Crash 1: use-after-free of handshake_state when a reassociation
overlaps a pending connection attempt.
netdev_connect() refuses to start while an attempt is pending
(netdev->connected || netdev->connect_cmd_id || netdev->work.id ->
-EISCONN). netdev_reassociate() has no equivalent guard, and the
station layer can invoke it mid-connect: station_cannot_roam() does
not cover the connecting states, connected_bss is already set while
connecting, and station_roam_scan_notify() does not re-check state.
Captured sequence (journal shows "state, old: connecting (auto), new:
roaming" in the same second as the crash):
1. A fresh SAE-H2E connect is queued behind a scan - the auth proto is
created holding its raw handshake pointer, netdev->work is queued
and never starts (sm->group_retry == -1 in the core).
2. A roam scan completes mid-connect -> netdev_reassociate() to a BSS
with a cached PMKSA. netdev_connect_common() takes the
PMKSA/CMD_CONNECT path, so netdev->ap is NOT replaced;
netdev->handshake is swapped; old_hs is unreffed here and the
caller swaps station->hs - both references gone, the handshake is
zeroed and freed under the stale auth proto. netdev_connect_common()
also re-inserts the already-queued embedded work item, linking the
same wiphy_radio_work_item into the queue twice.
3. The scan finishes -> the connect work runs ->
netdev_begin_connection() sends the CMD_CONNECT, then starts the
stale softmac auth proto -> sae_start() -> sae_choose_next_group()
reads sm->handshake->ecc_sae_pts from the freed (zeroed) handshake
-> NULL dereference.
Core anatomy: sm->handshake points at zeroed memory plus allocator
metadata; netdev->ap == sm while netdev->handshake is a different,
live handshake; station state == ROAMING.
Patch 2 adds the same guard netdev_connect() has. Both fields are
zero at any legitimate roam start since netdev_connect_ok() completes
the work item, and the station roam paths fail a rejected roam
cleanly - except station_preauthenticate_cb(), which is missing a
return in its error branch and falls through to handshake_state_ref()
on the new_hs it just unreffed. Patch 1 fixes that first so the new
error return cannot widen it.
Crash 2: station_ap_directed_roam() dereferences connected_bss before
its own state guard.
station_disconnect() clears connected_bss (via
station_reset_connection_state()) before entering DISCONNECTING, and
the WNM frame watch outlives the connection - so a BSS Transition
Management request arriving in that window (mesh APs send them around
disconnects; our journal shows connected -> disconnecting 2 s before
the crash) crashes on the ignore_candidates initializer that runs
before the guard meant to drop exactly that frame. The invariant
"state == CONNECTED => connected_bss != NULL" is otherwise sound -
the unguarded sanitize memcmp just below already relies on it.
Patch 3 assigns ignore_candidates after the state check.
Suchir Kavi (3):
station: fix use-after-free in preauthenticate_cb
netdev: reject reassociation while connect pending
station: fix NULL deref in ap_directed_roam
src/netdev.c | 3 +++
src/station.c | 7 +++++--
2 files changed, 8 insertions(+), 2 deletions(-)
--
2.54.0
next reply other threads:[~2026-07-16 2:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 2:34 Suchir Kavi [this message]
2026-07-16 2:34 ` [PATCH 1/3] station: fix use-after-free in preauthenticate_cb Suchir Kavi
2026-07-16 2:34 ` [PATCH 2/3] netdev: reject reassociation while connect pending Suchir Kavi
2026-07-16 2:34 ` [PATCH 3/3] station: fix NULL deref in ap_directed_roam Suchir Kavi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260716023444.3512595-1-suchirkavi@gmail.com \
--to=suchirkavi@gmail.com \
--cc=iwd@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox