summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-03-17 17:13:46 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2020-03-27 11:05:28 +0100
commitdbb6736d6bd2fa6e6c43ffeb6df2618111c8e4f2 (patch)
treeb579dd093fd3f965c6660d387dde1dd0d5dd39ff
parent96ab4ff47bef808ba0f72d9e92e2b130aea2e997 (diff)
downloadnetwork-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.c23
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);
}