diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-03-17 17:13:46 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-03-27 11:05:28 +0100 |
commit | dbb6736d6bd2fa6e6c43ffeb6df2618111c8e4f2 (patch) | |
tree | b579dd093fd3f965c6660d387dde1dd0d5dd39ff | |
parent | 96ab4ff47bef808ba0f72d9e92e2b130aea2e997 (diff) | |
download | network-manager-applet-bg/vpn-request-crash-rh1775278.tar.gz |
applet: fix crash in VPN secret dialog handlingbg/vpn-request-crash-rh1775278
If the VPN connection gets deactivated when the dialog is displayed,
the SecretsRequest is no longer valid. Accessing it in the dialog
callback causes a segmentation fault.
To fix this, disconnect the dialog handler when the secret request is
cancelled and install a new handler that just destroys the dialog.
https://bugzilla.redhat.com/show_bug.cgi?id=1775278
-rw-r--r-- | src/applet-vpn-request.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/applet-vpn-request.c b/src/applet-vpn-request.c index 47dd25db..79dc93be 100644 --- a/src/applet-vpn-request.c +++ b/src/applet-vpn-request.c @@ -50,6 +50,7 @@ typedef struct { /* These are just for the external UI mode */ EuiSecret *eui_secrets; + GtkDialog *dialog; } RequestData; typedef struct { @@ -124,7 +125,7 @@ external_ui_dialog_response (GtkDialog *dialog, int response_id, gpointer user_d } gtk_widget_destroy (GTK_WIDGET (dialog)); - g_object_unref (dialog); + g_clear_object (&req_data->dialog); external_ui_add_secrets (info); complete_request (info); } @@ -211,7 +212,7 @@ external_ui_from_child_response (VpnSecretsInfo *info, GError **error) * create a dialog and display it. */ if (num_ask > 0) { dialog = (NMAVpnPasswordDialog *) nma_vpn_password_dialog_new (title, message, NULL); - g_object_ref_sink (dialog); + req_data->dialog = g_object_ref_sink (dialog); nma_vpn_password_dialog_set_show_password (dialog, FALSE); nma_vpn_password_dialog_set_show_password_secondary (dialog, FALSE); @@ -593,6 +594,13 @@ ensure_killed (gpointer data) } static void +dialog_response_destroy (GtkDialog *dialog, int response_id, gpointer user_data) +{ + gtk_widget_destroy (GTK_WIDGET (dialog)); + g_object_unref (dialog); +} + +static void free_vpn_secrets_info (SecretsRequest *req) { @@ -637,6 +645,17 @@ free_vpn_secrets_info (SecretsRequest *req) g_free (req_data->eui_secrets); } + if (req_data->dialog) { + g_signal_handlers_disconnect_by_func (req_data->dialog, + external_ui_dialog_response, + req); + g_signal_connect (req_data->dialog, + "response", + G_CALLBACK (dialog_response_destroy), + NULL); + req_data->dialog = NULL; + } + g_slice_free (RequestData, req_data); } |