From 11797f4ad4c90015f8be58c6eb301d3eade44f57 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 20 Mar 2020 11:32:42 +0100 Subject: [PATCH] supplicant: fix crash setting supplicant state down When we receive a "InterfaceRemoved" signal, we will end up calling set_state_down(). That emits a "state" change signal, which causes NMDeviceWifi to unref the supplicant interface. This may already give up the last reference, and we cleanup the supplicant state (by again calling set_state_down()). When we return, set_state_down() will crash because it operates on an already destroyed instance. Avoid that by keeping a reference to the interface during set_state_down(). Fixes: b83f07916a54 ('supplicant: large rework of wpa_supplicant handling') https://bugzilla.redhat.com/show_bug.cgi?id=1815058 --- src/supplicant/nm-supplicant-interface.c | 1 + src/supplicant/nm-supplicant-manager.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c index 6edeef682a..42179246c8 100644 --- a/src/supplicant/nm-supplicant-interface.c +++ b/src/supplicant/nm-supplicant-interface.c @@ -947,6 +947,7 @@ set_state_down (NMSupplicantInterface *self, gboolean force_remove_from_supplicant, const char *reason) { + _nm_unused gs_unref_object NMSupplicantInterface *self_keep_alive = g_object_ref (self); NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); NMSupplicantBssInfo *bss_info; NMSupplicantPeerInfo *peer_info; diff --git a/src/supplicant/nm-supplicant-manager.c b/src/supplicant/nm-supplicant-manager.c index e66a778934..cf5cf11163 100644 --- a/src/supplicant/nm-supplicant-manager.c +++ b/src/supplicant/nm-supplicant-manager.c @@ -1053,6 +1053,10 @@ _supp_iface_remove_one (NMSupplicantManager *self, gboolean force_remove_from_supplicant, const char *reason) { +#if NM_MORE_ASSERTS + _nm_unused gs_unref_object NMSupplicantInterface *supp_iface_keep_alive = g_object_ref (supp_iface); +#endif + nm_assert (NM_IS_SUPPLICANT_MANAGER (self)); nm_assert (NM_IS_SUPPLICANT_INTERFACE (supp_iface)); nm_assert (c_list_contains (&NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->supp_lst_head, &supp_iface->supp_lst));