Re: [BUG] Crash in network_info_get_roam_frequencies() when a neighbor report completes with -ENOTCONN during disconnect teardown
James Prestwood <[email protected]> Tue, 28 Jul 2026 06:17:56 -0700
| Newsgroups | dev.linux.lists.iwd |
|---|---|
| Message-ID | <[email protected]> |
Hi Muhammed,
On 7/27/26 1:03 PM, Muhammed Izzet Saglam wrote:
> Hi,
>
> iwd 3.12 crashes with SIGSEGV while roaming, when a pending 802.11k
> neighbor report request completes during connection teardown. The
> neighbor report callback only bails out on -ENODEV, so an -ENOTCONN
> completion falls through to a roam scan that dereferences the connection
> state netdev_connect_free() has just torn down.
>
> I hit this twice within one minute on 2026-07-25 and captured both core
> dumps. The backtraces are identical, so this looks deterministic rather
> than memory corruption.
>
> Backtrace (both dumps, identical):
>
> #0 network_info_get_roam_frequencies (info=0x0, current_freq=2462,
> max=max@entry=5 '\005') at src/knownnetworks.c:391
> #1 station_roam_scan_known_freqs (station=station@entry=0x564903a82b50)
> at src/station.c:3088
> #2 station_neighbor_report_cb (netdev=<optimized out>, err=-107,
> reports=<optimized out>, reports_len=0,
> user_data=0x564903a82b50) at src/station.c:3129
> #3 netdev_connect_free (netdev=netdev@entry=0x564903a77c40)
> at src/netdev.c:867
> #4 netdev_connect_failed (netdev=0x564903a77c40, result=<optimized out>,
> status_or_reason=<optimized out>) at src/netdev.c:937
> #5 netdev_disconnected (netdev=0x564903a77c40, result=<optimized out>,
> event=NETDEV_EVENT_DISCONNECT_BY_SME,
> status_or_reason=<optimized out>) at src/netdev.c:1004
> #6 netdev_disconnect_by_sme_cb (msg=<optimized out>,
> user_data=0x564903a77c40) at src/netdev.c:1019
> #7 process_unicast (genl=<optimized out>, nlmsg=0x7ffffcf571d0)
> at ell/genl.c:860
> #8 received_data (io=<optimized out>, user_data=0x564903a69bb0)
> at ell/genl.c:972
> #9 io_callback (fd=<optimized out>, events=1, user_data=0x564903a69b00)
> at ell/io.c:105
> #10 l_main_iterate (timeout=<optimized out>) at ell/main.c:463
> #11 l_main_run () at ell/main.c:511
> #12 l_main_run () at ell/main.c:492
> #13 l_main_run_with_signal (callback=0x5648f3df5bc0 <signal_handler>,
> user_data=0x0) at ell/main.c:633
> #14 main (argc=<optimized out>, argv=<optimized out>) at src/main.c:610
>
> The faulting line is knownnetworks.c:391, with info == NULL:
>
> for (entry = l_queue_get_entries(info->known_frequencies); entry && max;
>
> Sequence, as I read it:
>
> 1. The AP disconnects us, so netdev_disconnect_by_sme_cb() runs
> (NETDEV_EVENT_DISCONNECT_BY_SME).
> 2. netdev_connect_failed() -> netdev_connect_free() tears the
> connection down and completes the outstanding neighbor report
> request with an error.
> 3. station_neighbor_report_cb() is invoked with err = -107
> (-ENOTCONN).
> 4. The guard at the top of that callback only returns early for
> -ENODEV:
>
> if (!station->preparing_roam || err == -ENODEV)
> return;
>
> so -ENOTCONN continues to:
>
> if (!reports || err) {
> r = station_roam_scan_known_freqs(station);
>
> 5. station_roam_scan_known_freqs() then reaches
> network_info_get_roam_frequencies() with the network info already
> gone, and dereferences NULL.
>
> Commit 155c266 ("station: add checks to prevent multiple roam scans",
> Jan 2023) fixed a different path to the same crash signature and is of
> course already in 3.12. This one arrives through the disconnect teardown
> rather than the roam rearm timer, and the code in master still looks
> affected: station_neighbor_report_cb() special-cases -ENODEV only, and
> station_roam_scan_known_freqs() has no NULL check on the connected
> network.
>
> I have not written a patch because I do not know which fix you would
> prefer -- treating any err as terminal in the callback, checking
> station->connected_network before the fallback scan, or cancelling the
> neighbor report request earlier in netdev_connect_free(). Happy to test
> a patch on this hardware.
>
> System:
>
> iwd 3.12 (Arch Linux, iwd 3.12-1)
> kernel 7.1.5-zen1-1-zen (x86_64)
> device Intel Wi-Fi 6E AX210/AX1675 2x2 [Typhoon Peak]
> [8086:2725] rev 1a, iwlwifi
> firmware 89.735b75a4.0 ty-a0-gf-a0-89.ucode, op_mode iwlmvm
> band at crash 2462 MHz (2.4 GHz, channel 11), roaming on a weak link
>
> Both core dumps are still on disk if anything else would help.
>
> Thanks,
> Muhammed Izzet Saglam
Thanks for reporting this. A quick fix is certainly to just add
-ENOTCONN to station_neighbor_report_cb(). The only thing that makes me
nervous is if -ENOTCONN is a possible return from netlink. I'm also
questioning why netdev needs to call the callback in the first place
(e.g. with -ENODEV). We just bail out and ignore it. I can see the
argument for netdev completing the API contract with the caller, but it
also feels like a waste of cycles to me.
Thanks,
James