[network-manager-applet/bg/vpn-request-crash-rh1775278: 2/2] applet: fix crash in VPN secret dialog handling



commit 3e360c8c061571e2bbde96ac0fc5c434fbf01999
Author: Beniamino Galvani <bgalvani redhat com>
Date:   Tue Mar 17 17:13:46 2020 +0100

    applet: fix crash in VPN secret dialog handling
    
    If the VPN connection gets deactivated when the dialog is displayed,
    the SecretsRequest is no longer valid. Referencing 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

 src/applet-vpn-request.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)
---
diff --git a/src/applet-vpn-request.c b/src/applet-vpn-request.c
index e52243c8..b1cfb370 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,6 +125,7 @@ external_ui_dialog_response (GtkDialog *dialog, int response_id, gpointer user_d
        }
 
        gtk_widget_destroy (GTK_WIDGET (dialog));
+       g_clear_object (&req_data->dialog);
        external_ui_add_secrets (info);
        complete_request (info);
 }
@@ -210,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 +595,13 @@ ensure_killed (gpointer data)
        return FALSE;
 }
 
+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)
 {
@@ -639,6 +648,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);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]