|
|
769eef0 |
From 018a0f889d18c41e314f0b1297d1dc559603142b Mon Sep 17 00:00:00 2001
|
|
|
d448651 |
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
|
769eef0 |
Date: Tue, 5 Feb 2019 18:36:04 +0900
|
|
|
0e0ffba |
Subject: [PATCH] Fix SEGV in bus_panel_proxy_focus_in()
|
|
|
0e0ffba |
|
|
|
0e0ffba |
rhbz#1349148, rhbz#1385349
|
|
|
0e0ffba |
SEGV in BUS_IS_PANEL_PROXY() in bus_panel_proxy_focus_in()
|
|
|
0e0ffba |
Check if GDBusConnect is closed before bus_panel_proxy_new() is called.
|
|
|
0e0ffba |
|
|
|
0e0ffba |
rhbz#1350291 SEGV in BUS_IS_CONNECTION(skip_connection) in
|
|
|
0e0ffba |
bus_dbus_impl_dispatch_message_by_rule()
|
|
|
0e0ffba |
check if dbus_connection is closed in bus_dbus_impl_connection_filter_cb().
|
|
|
0e0ffba |
|
|
|
0e0ffba |
rhbz#1406699 SEGV in new_owner!=NULL in bus_dbus_impl_name_owner_changed()
|
|
|
0e0ffba |
which is called by bus_name_service_remove_owner()
|
|
|
0e0ffba |
If bus_connection_get_unique_name()==NULL, set new_owner="" in
|
|
|
0e0ffba |
bus_name_service_remove_owner()
|
|
|
0e0ffba |
|
|
|
0e0ffba |
rhbz#1432252 SEGV in old_owner!=NULL in bus_dbus_impl_name_owner_changed()
|
|
|
0e0ffba |
which is called by bus_name_service_set_primary_owner()
|
|
|
0e0ffba |
If bus_connection_get_unique_name()==NULL, set old_owner="" in
|
|
|
0e0ffba |
bus_name_service_set_primary_owner()
|
|
|
0e0ffba |
|
|
|
0e0ffba |
rhbz#1601577 SEGV in ibus_engine_desc_get_layout() in
|
|
|
0e0ffba |
bus_engine_proxy_new_internal()
|
|
|
0e0ffba |
WIP: Added a GError to get the error message to check why the SEGV happened.
|
|
|
0e0ffba |
|
|
|
0e0ffba |
rhbz#1663528 SEGV in g_mutex_clear() in bus_dbus_impl_destroy()
|
|
|
0e0ffba |
If the mutex is not unlocked, g_mutex_clear() causes assert.
|
|
|
d448651 |
|
|
|
d448651 |
BUG=rhbz#1349148
|
|
|
d448651 |
BUG=rhbz#1385349
|
|
|
d448651 |
BUG=rhbz#1350291
|
|
|
3818b86 |
BUG=rhbz#1406699
|
|
|
3818b86 |
BUG=rhbz#1432252
|
|
|
d165013 |
BUG=rhbz#1601577
|
|
|
0e0ffba |
BUG=rhbz#1663528
|
|
|
d448651 |
---
|
|
|
769eef0 |
bus/dbusimpl.c | 70 +++++++++++++++++++++++++++++++++++++++++------
|
|
|
769eef0 |
bus/engineproxy.c | 9 +++++-
|
|
|
769eef0 |
bus/ibusimpl.c | 21 ++++++++++++--
|
|
|
769eef0 |
3 files changed, 88 insertions(+), 12 deletions(-)
|
|
|
d448651 |
|
|
|
d448651 |
diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c
|
|
|
769eef0 |
index b54ef817..fb38faf0 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.
|
|
|
0e0ffba |
+ * Copyright (C) 2015-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
|
0e0ffba |
+ * Copyright (C) 2008-2019 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
|
|
|
769eef0 |
@@ -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);
|
|
|
769eef0 |
@@ -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],
|
|
|
769eef0 |
@@ -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) {
|
|
|
769eef0 |
@@ -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);
|
|
|
769eef0 |
@@ -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) {
|
|
|
769eef0 |
@@ -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,
|
|
|
769eef0 |
@@ -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 |
}
|
|
|
769eef0 |
@@ -591,6 +610,7 @@ static void
|
|
|
769eef0 |
bus_dbus_impl_destroy (BusDBusImpl *dbus)
|
|
|
769eef0 |
{
|
|
|
769eef0 |
GList *p;
|
|
|
769eef0 |
+ int i;
|
|
|
0e0ffba |
|
|
|
769eef0 |
for (p = dbus->objects; p != NULL; p = p->next) {
|
|
|
769eef0 |
IBusService *object = (IBusService *) p->data;
|
|
|
769eef0 |
@@ -628,12 +648,39 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus)
|
|
|
769eef0 |
dbus->unique_names = NULL;
|
|
|
769eef0 |
dbus->names = NULL;
|
|
|
0e0ffba |
|
|
|
769eef0 |
+ for (i = 0; g_idle_remove_by_data (dbus); i++) {
|
|
|
769eef0 |
+ if (i > 1000) {
|
|
|
769eef0 |
+ g_warning ("Too many idle threads were generated by " \
|
|
|
769eef0 |
+ "bus_dbus_impl_forward_message_idle_cb and " \
|
|
|
769eef0 |
+ "bus_dbus_impl_dispatch_message_by_rule_idle_cb");
|
|
|
769eef0 |
+ break;
|
|
|
769eef0 |
+ }
|
|
|
769eef0 |
+ }
|
|
|
769eef0 |
g_list_free_full (dbus->start_service_calls,
|
|
|
0e0ffba |
(GDestroyNotify) bus_method_call_free);
|
|
|
0e0ffba |
dbus->start_service_calls = NULL;
|
|
|
0e0ffba |
|
|
|
0e0ffba |
- g_mutex_clear (&dbus->dispatch_lock);
|
|
|
0e0ffba |
- g_mutex_clear (&dbus->forward_lock);
|
|
|
769eef0 |
+ /* rhbz#1663528 Call g_mutex_trylock() before g_mutex_clear()
|
|
|
769eef0 |
+ * because if the mutex is not unlocked, g_mutex_clear() causes assert.
|
|
|
769eef0 |
+ */
|
|
|
769eef0 |
+#define BUS_DBUS_MUTEX_SAFE_CLEAR(mtex) { \
|
|
|
769eef0 |
+ int count = 0; \
|
|
|
769eef0 |
+ while (!g_mutex_trylock ((mtex))) { \
|
|
|
769eef0 |
+ g_usleep (1); \
|
|
|
769eef0 |
+ if (count > 60) { \
|
|
|
769eef0 |
+ g_warning (#mtex " is dead lock"); \
|
|
|
769eef0 |
+ break; \
|
|
|
769eef0 |
+ } \
|
|
|
769eef0 |
+ ++count; \
|
|
|
769eef0 |
+ } \
|
|
|
769eef0 |
+ g_mutex_unlock ((mtex)); \
|
|
|
769eef0 |
+ g_mutex_clear ((mtex)); \
|
|
|
769eef0 |
+}
|
|
|
0e0ffba |
+
|
|
|
769eef0 |
+ BUS_DBUS_MUTEX_SAFE_CLEAR (&dbus->dispatch_lock);
|
|
|
769eef0 |
+ BUS_DBUS_MUTEX_SAFE_CLEAR (&dbus->forward_lock);
|
|
|
769eef0 |
+
|
|
|
769eef0 |
+#undef BUS_DBUS_MUTEX_SAFE_CLEAR
|
|
|
0e0ffba |
|
|
|
0e0ffba |
/* FIXME destruct _lock and _queue members. */
|
|
|
0e0ffba |
IBUS_OBJECT_CLASS(bus_dbus_impl_parent_class)->destroy ((IBusObject *) dbus);
|
|
|
769eef0 |
@@ -1464,13 +1511,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 */
|
|
|
d165013 |
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
|
|
|
0e0ffba |
index 2d98995c..2176e0c9 100644
|
|
|
d165013 |
--- a/bus/engineproxy.c
|
|
|
d165013 |
+++ b/bus/engineproxy.c
|
|
|
d165013 |
@@ -665,6 +665,7 @@ bus_engine_proxy_new_internal (const gchar *path,
|
|
|
d165013 |
IBusEngineDesc *desc,
|
|
|
d165013 |
GDBusConnection *connection)
|
|
|
d165013 |
{
|
|
|
d165013 |
+ GError *error = NULL;
|
|
|
d165013 |
g_assert (path);
|
|
|
d165013 |
g_assert (IBUS_IS_ENGINE_DESC (desc));
|
|
|
d165013 |
g_assert (G_IS_DBUS_CONNECTION (connection));
|
|
|
d165013 |
@@ -673,7 +674,7 @@ bus_engine_proxy_new_internal (const gchar *path,
|
|
|
d165013 |
BusEngineProxy *engine =
|
|
|
d165013 |
(BusEngineProxy *) g_initable_new (BUS_TYPE_ENGINE_PROXY,
|
|
|
d165013 |
NULL,
|
|
|
d165013 |
- NULL,
|
|
|
d165013 |
+ &error,
|
|
|
d165013 |
"desc", desc,
|
|
|
d165013 |
"g-connection", connection,
|
|
|
d165013 |
"g-interface-name", IBUS_INTERFACE_ENGINE,
|
|
|
0e0ffba |
@@ -681,6 +682,12 @@ bus_engine_proxy_new_internal (const gchar *path,
|
|
|
d165013 |
"g-default-timeout", g_gdbus_timeout,
|
|
|
d165013 |
"g-flags", flags,
|
|
|
d165013 |
NULL);
|
|
|
d165013 |
+ /* FIXME: rhbz#1601577 */
|
|
|
0e0ffba |
+ if (error) {
|
|
|
0e0ffba |
+ /* show abrt local variable */
|
|
|
0e0ffba |
+ gchar *message = g_strdup (error->message);
|
|
|
0e0ffba |
+ g_error ("%s", message);
|
|
|
0e0ffba |
+ }
|
|
|
d165013 |
const gchar *layout = ibus_engine_desc_get_layout (desc);
|
|
|
d165013 |
if (layout != NULL && layout[0] != '\0') {
|
|
|
d165013 |
engine->keymap = ibus_keymap_get (layout);
|
|
|
d448651 |
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
|
|
|
0e0ffba |
index bbbb5770..77fcf42f 100644
|
|
|
d448651 |
--- a/bus/ibusimpl.c
|
|
|
d448651 |
+++ b/bus/ibusimpl.c
|
|
|
0e0ffba |
@@ -464,13 +464,16 @@ _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
|
|
|
6784864 |
else if (!g_strcmp0 (name, IBUS_SERVICE_PANEL_EXTENSION_EMOJI))
|
|
|
6784864 |
panel_type = PANEL_TYPE_EXTENSION_EMOJI;
|
|
|
d448651 |
|
|
|
98919f7 |
- if (panel_type != PANEL_TYPE_NONE) {
|
|
|
d448651 |
+ do {
|
|
|
98919f7 |
+ if (panel_type == PANEL_TYPE_NONE)
|
|
|
d448651 |
+ break;
|
|
|
d448651 |
if (g_strcmp0 (new_name, "") != 0) {
|
|
|
d448651 |
/* a Panel process is started. */
|
|
|
d448651 |
BusConnection *connection;
|
|
|
d448651 |
BusInputContext *context = NULL;
|
|
|
98919f7 |
BusPanelProxy **panel = (panel_type == PANEL_TYPE_PANEL) ?
|
|
|
6784864 |
&ibus->panel : &ibus->emoji_extension;
|
|
|
d448651 |
+ GDBusConnection *dbus_connection = NULL;
|
|
|
d448651 |
|
|
|
98919f7 |
if (*panel != NULL) {
|
|
|
98919f7 |
ibus_proxy_destroy ((IBusProxy *)(*panel));
|
|
|
0e0ffba |
@@ -479,9 +482,21 @@ _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
|
|
|
98919f7 |
g_assert (*panel == NULL);
|
|
|
98919f7 |
}
|
|
|
98919f7 |
|
|
|
98919f7 |
- connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
|
|
|
98919f7 |
+ connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS,
|
|
|
98919f7 |
+ new_name);
|
|
|
d448651 |
g_return_if_fail (connection != NULL);
|
|
|
d448651 |
|
|
|
d448651 |
+ dbus_connection = bus_connection_get_dbus_connection (connection);
|
|
|
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 |
+
|
|
|
98919f7 |
*panel = bus_panel_proxy_new (connection, panel_type);
|
|
|
6784864 |
if (panel_type == PANEL_TYPE_EXTENSION_EMOJI)
|
|
|
6784864 |
ibus->enable_emoji_extension = FALSE;
|
|
|
0e0ffba |
@@ -535,7 +550,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 |
--
|
|
|
769eef0 |
2.20.1
|
|
|
d448651 |
|