Wireless Daemon for Linux
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix two station roaming crashes
@ 2026-07-16  2:34 Suchir Kavi
  2026-07-16  2:34 ` [PATCH 1/3] station: fix use-after-free in preauthenticate_cb Suchir Kavi
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Suchir Kavi @ 2026-07-16  2:34 UTC (permalink / raw)
  To: iwd

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-16  2:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16  2:34 [PATCH 0/3] Fix two station roaming crashes Suchir Kavi
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox