wifi: fix list corruption when scanning with explicit SSID

Calling c_list_link_tail() on a list entry that already belongs to
another list corrupts the other list, in this case 'old_lst_head';
this is explained in the documentation of c_list_link_before():

 * @what is not inspected prior to being linked. Hence, it better not
 * be linked into another list, or the other list will be corrupted.

This can be reproduced by invoking "nmcli device wifi rescan ssid x"
multiple times; in this way, _scan_request_ssids_track() reuses the
previous SSID data, the list gets corrupted and this causes a crash.

Fixes: 7500e90b53 ('wifi: rework scanning of Wi-Fi device')

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2076
(cherry picked from commit 3b75577871)
(cherry picked from commit 3917235a2d)
(cherry picked from commit 409acc6185)
(cherry picked from commit 1006b39ef1)
This commit is contained in:
Beniamino Galvani 2024-11-21 22:51:29 +01:00 committed by Íñigo Huguet
parent 810de21d03
commit 4685ceaa67

View file

@ -327,7 +327,7 @@ _scan_request_ssids_track(NMDeviceWifiPrivate *priv, const GPtrArray *ssids)
priv->scan_request_ssids_hash = g_hash_table_new(nm_pg_bytes_hash, nm_pg_bytes_equal);
/* Do a little dance. New elements shall keep their order as in @ssids, but all
* new elements should be sorted in the list preexisting elements of the list.
* new elements should be sorted before preexisting elements of the list.
* First move the old elements away, and splice them back afterwards. */
c_list_init(&old_lst_head);
c_list_splice(&old_lst_head, &priv->scan_request_ssids_lst_head);
@ -348,6 +348,8 @@ _scan_request_ssids_track(NMDeviceWifiPrivate *priv, const GPtrArray *ssids)
g_hash_table_add(priv->scan_request_ssids_hash, d);
} else
d->timestamp_msec = now_msec;
c_list_unlink_stale(&d->lst);
c_list_link_tail(&priv->scan_request_ssids_lst_head, &d->lst);
}