[network-manager-applet: 4/5] applet: fix crash in VPN secret dialog handling



commit b6397279f9efd8beb9f8449dbaca9dd425b588cc
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. 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

 src/applet-vpn-request.c | 23 +++++++++++++++++++++--
 1 file 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);
@@ -592,6 +593,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)
 {
@@ -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);
 }
 


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