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