3818b86
From 8ea0d3f25078c612b4b16c955c1c0c17e764d8c5 Mon Sep 17 00:00:00 2001
d448651
From: fujiwarat <takao.fujiwara1@gmail.com>
3818b86
Date: Thu, 27 Jul 2017 18:56:01 +0900
d448651
Subject: [PATCH] bus: Fix SEGV in bus_panel_proxy_focus_in()
d448651
d448651
BUG=rhbz#1349148
d448651
BUG=rhbz#1385349
d448651
BUG=rhbz#1350291
3818b86
BUG=rhbz#1406699
3818b86
BUG=rhbz#1432252
d448651
---
3818b86
 bus/dbusimpl.c | 38 ++++++++++++++++++++++++++++++++------
d448651
 bus/ibusimpl.c | 22 +++++++++++++++++++---
3818b86
 2 files changed, 51 insertions(+), 9 deletions(-)
d448651
d448651
diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c
3818b86
index b54ef81..e4dd868 100644
d448651
--- a/bus/dbusimpl.c
d448651
+++ b/bus/dbusimpl.c
d448651
@@ -2,7 +2,8 @@
d448651
 /* vim:set et sts=4: */
d448651
 /* ibus - The Input Bus
d448651
  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
d448651
- * Copyright (C) 2008-2013 Red Hat, Inc.
d448651
+ * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
d448651
+ * Copyright (C) 2008-2017 Red Hat, Inc.
d448651
  *
d448651
  * This library is free software; you can redistribute it and/or
d448651
  * modify it under the terms of the GNU Lesser General Public
3818b86
@@ -344,6 +345,8 @@ bus_name_service_set_primary_owner (BusNameService     *service,
3818b86
                                     BusConnectionOwner *owner,
3818b86
                                     BusDBusImpl        *dbus)
3818b86
 {
3818b86
+    gboolean has_old_owner = FALSE;
3818b86
+
3818b86
     g_assert (service != NULL);
3818b86
     g_assert (owner != NULL);
3818b86
     g_assert (dbus != NULL);
3818b86
@@ -351,6 +354,13 @@ bus_name_service_set_primary_owner (BusNameService     *service,
3818b86
     BusConnectionOwner *old = service->owners != NULL ?
3818b86
             (BusConnectionOwner *)service->owners->data : NULL;
3818b86
 
3818b86
+    /* rhbz#1432252 If bus_connection_get_unique_name() == NULL,
3818b86
+     * "Hello" method is not received yet.
3818b86
+     */
3818b86
+    if (old != NULL && bus_connection_get_unique_name (old->conn) != NULL) {
3818b86
+        has_old_owner = TRUE;
3818b86
+    }
3818b86
+
3818b86
     if (old != NULL) {
3818b86
         g_signal_emit (dbus,
3818b86
                        dbus_signals[NAME_LOST],
3818b86
@@ -370,7 +380,8 @@ bus_name_service_set_primary_owner (BusNameService     *service,
3818b86
                    0,
3818b86
                    owner->conn,
3818b86
                    service->name,
3818b86
-                   old != NULL ? bus_connection_get_unique_name (old->conn) : "",
3818b86
+                   has_old_owner ? bus_connection_get_unique_name (old->conn) :
3818b86
+                           "",
3818b86
                    bus_connection_get_unique_name (owner->conn));
3818b86
 
3818b86
     if (old != NULL && old->do_not_queue != 0) {
3818b86
@@ -427,6 +438,7 @@ bus_name_service_remove_owner (BusNameService     *service,
3818b86
                                BusDBusImpl        *dbus)
3818b86
 {
3818b86
     GSList *owners;
3818b86
+    gboolean has_new_owner = FALSE;
3818b86
 
3818b86
     g_assert (service != NULL);
3818b86
     g_assert (owner != NULL);
3818b86
@@ -439,6 +451,13 @@ bus_name_service_remove_owner (BusNameService     *service,
3818b86
         BusConnectionOwner *_new = NULL;
3818b86
         if (owners->next != NULL) {
3818b86
             _new = (BusConnectionOwner *)owners->next->data;
3818b86
+            /* rhbz#1406699 If bus_connection_get_unique_name() == NULL,
3818b86
+             * "Hello" method is not received yet.
3818b86
+             */
3818b86
+            if (_new != NULL &&
3818b86
+                bus_connection_get_unique_name (_new->conn) != NULL) {
3818b86
+                has_new_owner = TRUE;
3818b86
+            }
3818b86
         }
3818b86
 
3818b86
         if (dbus != NULL) {
3818b86
@@ -447,7 +466,7 @@ bus_name_service_remove_owner (BusNameService     *service,
3818b86
                            0,
3818b86
                            owner->conn,
3818b86
                            service->name);
3818b86
-            if (_new != NULL) {
3818b86
+            if (has_new_owner) {
3818b86
                 g_signal_emit (dbus,
3818b86
                                dbus_signals[NAME_ACQUIRED],
3818b86
                                0,
3818b86
@@ -460,7 +479,7 @@ bus_name_service_remove_owner (BusNameService     *service,
3818b86
                     _new != NULL ? _new->conn : NULL,
3818b86
                     service->name,
3818b86
                     bus_connection_get_unique_name (owner->conn),
3818b86
-                    _new != NULL ? bus_connection_get_unique_name (_new->conn) : "");
3818b86
+                    has_new_owner ? bus_connection_get_unique_name (_new->conn) : "");
3818b86
 
3818b86
         }
3818b86
     }
3818b86
@@ -1464,13 +1483,20 @@ bus_dbus_impl_connection_filter_cb (GDBusConnection *dbus_connection,
d448651
                                     gboolean         incoming,
d448651
                                     gpointer         user_data)
d448651
 {
d448651
+    BusDBusImpl *dbus;
d448651
+    BusConnection *connection;
d448651
+
d448651
     g_assert (G_IS_DBUS_CONNECTION (dbus_connection));
d448651
     g_assert (G_IS_DBUS_MESSAGE (message));
d448651
     g_assert (BUS_IS_DBUS_IMPL (user_data));
d448651
 
d448651
-    BusDBusImpl *dbus = (BusDBusImpl *) user_data;
d448651
-    BusConnection *connection = bus_connection_lookup (dbus_connection);
d448651
+    if (g_dbus_connection_is_closed (dbus_connection))
d448651
+        return NULL;
d448651
+
d448651
+    dbus = (BusDBusImpl *) user_data;
d448651
+    connection = bus_connection_lookup (dbus_connection);
d448651
     g_assert (connection != NULL);
d448651
+    g_assert (BUS_IS_CONNECTION (connection));
d448651
 
d448651
     if (incoming) {
d448651
         /* is incoming message */
d448651
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
d448651
index f99307a..2d43ff6 100644
d448651
--- a/bus/ibusimpl.c
d448651
+++ b/bus/ibusimpl.c
d448651
@@ -2,7 +2,8 @@
d448651
 /* vim:set et sts=4: */
d448651
 /* ibus - The Input Bus
d448651
  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
d448651
- * Copyright (C) 2008-2013 Red Hat, Inc.
d448651
+ * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
d448651
+ * Copyright (C) 2008-2017 Red Hat, Inc.
d448651
  *
d448651
  * This library is free software; you can redistribute it and/or
d448651
  * modify it under the terms of the GNU Lesser General Public
d448651
@@ -323,11 +324,14 @@ _dbus_name_owner_changed_cb (BusDBusImpl   *dbus,
d448651
     g_assert (new_name != NULL);
d448651
     g_assert (BUS_IS_IBUS_IMPL (ibus));
d448651
 
d448651
-    if (g_strcmp0 (name, IBUS_SERVICE_PANEL) == 0) {
d448651
+    do {
d448651
+        if (g_strcmp0 (name, IBUS_SERVICE_PANEL) != 0)
d448651
+            break;
d448651
         if (g_strcmp0 (new_name, "") != 0) {
d448651
             /* a Panel process is started. */
d448651
             BusConnection *connection;
d448651
             BusInputContext *context = NULL;
d448651
+            GDBusConnection *dbus_connection = NULL;
d448651
 
d448651
             if (ibus->panel != NULL) {
d448651
                 ibus_proxy_destroy ((IBusProxy *) ibus->panel);
d448651
@@ -338,6 +342,18 @@ _dbus_name_owner_changed_cb (BusDBusImpl   *dbus,
d448651
             connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
d448651
             g_return_if_fail (connection != NULL);
d448651
 
d448651
+            dbus_connection = bus_connection_get_dbus_connection (connection);
d448651
+
d448651
+            /* rhbz#1349148 rhbz#1385349
d448651
+             * Avoid SEGV of BUS_IS_PANEL_PROXY (ibus->panel)
d448651
+             * This function is called during destroying the connection
d448651
+             * in this case? */
d448651
+            if (dbus_connection == NULL ||
d448651
+                g_dbus_connection_is_closed (dbus_connection)) {
d448651
+                new_name = "";
d448651
+                break;
d448651
+            }
d448651
+
d448651
             ibus->panel = bus_panel_proxy_new (connection);
d448651
 
d448651
             g_signal_connect (ibus->panel,
d448651
@@ -366,7 +382,7 @@ _dbus_name_owner_changed_cb (BusDBusImpl   *dbus,
d448651
                 }
d448651
             }
d448651
         }
d448651
-    }
d448651
+    } while (0);
d448651
 
d448651
     bus_ibus_impl_component_name_owner_changed (ibus, name, old_name, new_name);
d448651
 }
d448651
-- 
d448651
2.9.3
d448651