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



commit dbb6736d6bd2fa6e6c43ffeb6df2618111c8e4f2
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]