Blob Blame History Raw
From bbf4e50950a43fd4701f169baed22d58f7c4150b Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Fri, 2 Jun 2017 11:57:03 +0200
Subject: [PATCH] editor: fix crash when destroying 802.1x page

EAP methods keep a pointer to wireless-security without holding any
reference to it (to avoid a circular dependency). Thus, their lifetime
must be shorter than the wireless-security's.

When the page is disposed, EAP methods are kept alive because they are
referenced by the combo box displayed in the page. When the page is
destroyed, they try to access the wireless-security that is already
gone.

Fix this by removing the security widgets from the page before
destroying the wireless-security, so that EAP methods instances don't
stay around longer and are disposed at the same time of
wireless-security.

==11224== Invalid read of size 8
==11224==    at 0x444FA1: wireless_security_set_userpass (wireless-security.c:220)
==11224==    by 0x93033E4: g_closure_invoke (in /usr/lib64/libgobject-2.0.so.0.5000.3)
             [...]
==11224==    by 0x5DB3BBF: gtk_widget_unrealize (gtkwidget.c:5520)
==11224==    by 0x5DB63DF: gtk_widget_dispose (gtkwidget.c:12065)
==11224==    by 0x5DC9E47: gtk_window_dispose (gtkwindow.c:3151)
==11224==    by 0x9309AE8: g_object_run_dispose (in /usr/lib64/libgobject-2.0.so.0.5000.3)
==11224==    by 0x415F98: dispose (nm-connection-editor.c:513)
==11224==  Address 0x1c635820 is 64 bytes inside a block of size 136 free'd
==11224==    at 0x4C2ED4A: free (vg_replace_malloc.c:530)
==11224==    by 0x97996CD: g_free (in /usr/lib64/libglib-2.0.so.0.5000.3)
==11224==    by 0x97B221F: g_slice_free1 (in /usr/lib64/libglib-2.0.so.0.5000.3)
==11224==    by 0x41FE99: dispose (page-8021x-security.c:222)
==11224==    by 0x9308095: g_object_unref (in /usr/lib64/libgobject-2.0.so.0.5000.3)
==11224==    by 0x97B321C: g_slist_foreach (in /usr/lib64/libglib-2.0.so.0.5000.3)
==11224==    by 0x97B323A: g_slist_free_full (in /usr/lib64/libglib-2.0.so.0.5000.3)
==11224==    by 0x415E77: dispose (nm-connection-editor.c:495)
==11224==  Block was alloc'd at
==11224==    at 0x4C2DB9D: malloc (vg_replace_malloc.c:299)
==11224==    by 0x97995B8: g_malloc (in /usr/lib64/libglib-2.0.so.0.5000.3)
==11224==    by 0x97B1B12: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.5000.3)
==11224==    by 0x97B213D: g_slice_alloc0 (in /usr/lib64/libglib-2.0.so.0.5000.3)
==11224==    by 0x444DD8: wireless_security_init (wireless-security.c:160)
==11224==    by 0x448381: ws_wpa_eap_new (ws-wpa-eap.c:107)
==11224==    by 0x41FF22: finish_setup (page-8021x-security.c:69)
==11224==    by 0x93033E4: g_closure_invoke (in /usr/lib64/libgobject-2.0.so.0.5000.3)
==11224==    by 0x931E05E: g_signal_emit_valist (in /usr/lib64/libgobject-2.0.so.0.5000.3)
==11224==    by 0x931E43E: g_signal_emit (in /usr/lib64/libgobject-2.0.so.0.5000.3)
==11224==    by 0x41CFEA: emit_initialized (ce-page.c:667)
==11224==    by 0x41CFEA: ce_page_complete_init (ce-page.c:719)
==11224==    by 0x416EEA: get_secrets_cb (nm-connection-editor.c:822)
==11224==    by 0x8FD82B6: g_simple_async_result_complete (in /usr/lib64/libgio-2.0.so.0.5000.3)
==11224==    by 0x7466F58: get_secrets_cb (nm-remote-connection.c:456)

Fixes: 39bf39a394f94619d1135d48968704c09924c98b
https://bugzilla.redhat.com/show_bug.cgi?id=1458567
(cherry picked from commit 03c0bcf48f5d61b91d6baded8ecc9e76e2222cbe)
---
 src/connection-editor/page-8021x-security.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/connection-editor/page-8021x-security.c b/src/connection-editor/page-8021x-security.c
index b1904c7..9fde940 100644
--- a/src/connection-editor/page-8021x-security.c
+++ b/src/connection-editor/page-8021x-security.c
@@ -199,8 +199,14 @@ ce_page_8021x_security_init (CEPage8021xSecurity *self)
 static void
 dispose (GObject *object)
 {
+	CEPage *parent = CE_PAGE (object);
 	CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (object);
 
+	if (priv->security_widget) {
+		gtk_container_remove (GTK_CONTAINER (parent->page), priv->security_widget);
+		priv->security_widget = NULL;
+	}
+
 	if (priv->security) {
 		wireless_security_unref (priv->security);
 		priv->security = NULL;
-- 
2.9.3