From e6bf047ccc334fcefd8e4b82acac534217bb3d91 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 16 Dec 2016 12:50:11 +0100 Subject: [PATCH] wifi: cancel get-secrets request in wifi device I got an assertion failure: wifi_secrets_cb: assertion 'nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH' failed with backtrace [1]. I think, we have to keep track of the pending secrets request and cancel it when the device state changes. [1]: #0 0x00007fad615a7a21 _g_log_abort (libglib-2.0.so.0) #1 0x00007fad615a8e2d g_logv (libglib-2.0.so.0) #2 0x00007fad615a8f8f g_log (libglib-2.0.so.0) #3 0x000055e45e3fc718 get_secrets_cb (NetworkManager) #4 0x000055e45e3dfada _get_secrets_info_callback (NetworkManager) #5 0x000055e45e460d8d req_complete_release (NetworkManager) #6 0x000055e45e462a7f _con_get_try_complete_early (NetworkManager) #7 0x000055e45e462cb6 request_start (NetworkManager) #8 0x00007fad6159e8e7 g_idle_dispatch (libglib-2.0.so.0) #9 0x00007fad615a1e42 g_main_dispatch (libglib-2.0.so.0) #10 0x00007fad615a21c0 g_main_context_iterate (libglib-2.0.so.0) #11 0x00007fad615a24e2 g_main_loop_run (libglib-2.0.so.0) #12 0x000055e45e2bf561 main (NetworkManager) #13 0x00007fad60d97401 __libc_start_main (libc.so.6) #14 0x000055e45e2bfc6a _start (NetworkManager) --- src/devices/wifi/nm-device-wifi.c | 82 +++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 039c614fe1..4c56aa7c65 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -108,6 +108,8 @@ typedef struct { NM80211Mode mode; + NMActRequestGetSecretsCallId wifi_secrets_id; + guint periodic_source_id; guint link_timeout_id; guint32 failed_iface_count; @@ -1738,12 +1740,23 @@ wifi_secrets_cb (NMActRequest *req, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMDevice *device = user_data; + NMDeviceWifi *self = user_data; + NMDeviceWifiPrivate *priv; - if (req != nm_device_get_act_request (device)) + g_return_if_fail (NM_IS_DEVICE_WIFI (self)); + g_return_if_fail (NM_IS_ACT_REQUEST (req)); + + priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + g_return_if_fail (priv->wifi_secrets_id == call_id); + + priv->wifi_secrets_id = NULL; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; + g_return_if_fail (req == nm_device_get_act_request (device)); g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); g_return_if_fail (nm_act_request_get_settings_connection (req) == connection); @@ -1756,6 +1769,39 @@ wifi_secrets_cb (NMActRequest *req, nm_device_activate_schedule_stage1_device_prepare (device); } +static void +wifi_secrets_cancel (NMDeviceWifi *self) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + if (priv->wifi_secrets_id) + nm_act_request_cancel_secrets (NULL, priv->wifi_secrets_id); + nm_assert (!priv->wifi_secrets_id); +} + +static void +wifi_secrets_get_secrets (NMDeviceWifi *self, + const char *setting_name, + NMSecretAgentGetSecretsFlags flags) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMActRequest *req; + + wifi_secrets_cancel (self); + + req = nm_device_get_act_request (NM_DEVICE (self)); + g_return_if_fail (NM_IS_ACT_REQUEST (req)); + + priv->wifi_secrets_id = nm_act_request_get_secrets (req, + TRUE, + setting_name, + flags, + NULL, + wifi_secrets_cb, + self); + g_return_if_fail (priv->wifi_secrets_id); +} + /* * link_timeout_cb * @@ -1900,14 +1946,10 @@ handle_8021x_or_psk_auth_fail (NMDeviceWifi *self, cleanup_association_attempt (self, TRUE); nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - nm_act_request_get_secrets (req, - FALSE, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION - | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, - NULL, - wifi_secrets_cb, - self); + wifi_secrets_get_secrets (self, + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION + | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); handled = TRUE; } @@ -2172,7 +2214,7 @@ handle_auth_or_fail (NMDeviceWifi *self, if (!req) { req = nm_device_get_act_request (NM_DEVICE (self)); - g_assert (req); + g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); } applied_connection = nm_act_request_get_applied_connection (req); @@ -2186,12 +2228,9 @@ handle_auth_or_fail (NMDeviceWifi *self, nm_act_request_clear_secrets (req); setting_name = nm_connection_need_secrets (applied_connection, NULL); if (setting_name) { - NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - - if (new_secrets) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - nm_act_request_get_secrets (req, FALSE, setting_name, flags, NULL, wifi_secrets_cb, self); - + wifi_secrets_get_secrets (self, setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION + | (new_secrets ? NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW : 0)); g_object_set_data (G_OBJECT (applied_connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else @@ -2879,6 +2918,9 @@ device_state_changed (NMDevice *device, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); gboolean clear_aps = FALSE; + if (new_state > NM_DEVICE_STATE_ACTIVATED) + wifi_secrets_cancel (self); + if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) { /* Clean up the supplicant interface because in these states the * device cannot be used. @@ -3029,6 +3071,8 @@ dispose (GObject *object) nm_clear_g_source (&priv->periodic_source_id); + wifi_secrets_cancel (self); + cleanup_association_attempt (self, TRUE); supplicant_interface_release (self); cleanup_supplicant_failures (self); @@ -3151,7 +3195,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) klass->scanning_allowed = scanning_allowed; - /* Properties */ obj_properties[PROP_MODE] = g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "", NM_802_11_MODE_UNKNOWN, @@ -3193,7 +3236,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - /* Signals */ signals[ACCESS_POINT_ADDED] = g_signal_new (NM_DEVICE_WIFI_ACCESS_POINT_ADDED, G_OBJECT_CLASS_TYPE (object_class),