|
|
e79fdb |
From 66dd82116845addb08973d52e518db6e7ce5ff22 Mon Sep 17 00:00:00 2001
|
|
|
e79fdb |
From: Milan Crha <mcrha@redhat.com>
|
|
|
e79fdb |
Date: Mon, 8 May 2017 17:21:58 -0500
|
|
|
e79fdb |
Subject: [PATCH] Fix use after free when returned objects hold only one ref
|
|
|
e79fdb |
|
|
|
e79fdb |
It seems that not all code expects atk_object_ref_accessible_child()
|
|
|
e79fdb |
returning NULL, neither that it can return an object with only one
|
|
|
e79fdb |
reference, thus the following unref in the code can cause use-after-free
|
|
|
e79fdb |
eventually.
|
|
|
e79fdb |
|
|
|
e79fdb |
At least the chunk in impl_GetChildAtIndex() avoids runtime warning about
|
|
|
e79fdb |
invalid object being passed to g_object_unref(), which happened, in this
|
|
|
e79fdb |
case, when evolution returned NULL. Evolution returns objects with one
|
|
|
e79fdb |
reference only often, which tries to address the other chunks here.
|
|
|
e79fdb |
|
|
|
e79fdb |
https://bugzilla.gnome.org/show_bug.cgi?id=781716
|
|
|
e79fdb |
---
|
|
|
e79fdb |
atk-adaptor/adaptors/accessible-adaptor.c | 3 ++-
|
|
|
e79fdb |
atk-adaptor/adaptors/collection-adaptor.c | 16 ++++++++++++----
|
|
|
e79fdb |
2 files changed, 14 insertions(+), 5 deletions(-)
|
|
|
e79fdb |
|
|
|
e79fdb |
diff --git a/atk-adaptor/adaptors/accessible-adaptor.c b/atk-adaptor/adaptors/accessible-adaptor.c
|
|
|
e79fdb |
index 058b116..572e4f8 100644
|
|
|
e79fdb |
--- a/atk-adaptor/adaptors/accessible-adaptor.c
|
|
|
e79fdb |
+++ b/atk-adaptor/adaptors/accessible-adaptor.c
|
|
|
e79fdb |
@@ -182,7 +182,8 @@ impl_GetChildAtIndex (DBusConnection * bus,
|
|
|
e79fdb |
}
|
|
|
e79fdb |
child = atk_object_ref_accessible_child (object, i);
|
|
|
e79fdb |
reply = spi_object_return_reference (message, child);
|
|
|
e79fdb |
- g_object_unref (child);
|
|
|
e79fdb |
+ if (child)
|
|
|
e79fdb |
+ g_object_unref (child);
|
|
|
e79fdb |
|
|
|
e79fdb |
return reply;
|
|
|
e79fdb |
}
|
|
|
e79fdb |
diff --git a/atk-adaptor/adaptors/collection-adaptor.c b/atk-adaptor/adaptors/collection-adaptor.c
|
|
|
e79fdb |
index 42ea073..b57c5f6 100644
|
|
|
e79fdb |
--- a/atk-adaptor/adaptors/collection-adaptor.c
|
|
|
e79fdb |
+++ b/atk-adaptor/adaptors/collection-adaptor.c
|
|
|
e79fdb |
@@ -494,9 +494,12 @@ sort_order_canonical (MatchRulePrivate * mrp, GList * ls,
|
|
|
e79fdb |
{
|
|
|
e79fdb |
AtkObject *child = atk_object_ref_accessible_child (obj, i);
|
|
|
e79fdb |
|
|
|
e79fdb |
- g_object_unref (child);
|
|
|
e79fdb |
+ if (!child)
|
|
|
e79fdb |
+ continue;
|
|
|
e79fdb |
+
|
|
|
e79fdb |
if (prev && child == pobj)
|
|
|
e79fdb |
{
|
|
|
e79fdb |
+ g_object_unref (child);
|
|
|
e79fdb |
return kount;
|
|
|
e79fdb |
}
|
|
|
e79fdb |
|
|
|
e79fdb |
@@ -517,6 +520,7 @@ sort_order_canonical (MatchRulePrivate * mrp, GList * ls,
|
|
|
e79fdb |
kount = sort_order_canonical (mrp, ls, kount,
|
|
|
e79fdb |
max, child, 0, TRUE,
|
|
|
e79fdb |
pobj, recurse, traverse);
|
|
|
e79fdb |
+ g_object_unref (child);
|
|
|
e79fdb |
}
|
|
|
e79fdb |
return kount;
|
|
|
e79fdb |
}
|
|
|
e79fdb |
@@ -559,19 +563,23 @@ sort_order_rev_canonical (MatchRulePrivate * mrp, GList * ls,
|
|
|
e79fdb |
and get it's last descendant.
|
|
|
e79fdb |
First, get the previous sibling */
|
|
|
e79fdb |
nextobj = atk_object_ref_accessible_child (parent, indexinparent - 1);
|
|
|
e79fdb |
- g_object_unref (nextobj);
|
|
|
e79fdb |
|
|
|
e79fdb |
/* Now, drill down the right side to the last descendant */
|
|
|
e79fdb |
- while (atk_object_get_n_accessible_children (nextobj) > 0)
|
|
|
e79fdb |
+ while (nextobj && atk_object_get_n_accessible_children (nextobj) > 0)
|
|
|
e79fdb |
{
|
|
|
e79fdb |
- nextobj = atk_object_ref_accessible_child (nextobj,
|
|
|
e79fdb |
+ AtkObject *follow;
|
|
|
e79fdb |
+
|
|
|
e79fdb |
+ follow = atk_object_ref_accessible_child (nextobj,
|
|
|
e79fdb |
atk_object_get_n_accessible_children
|
|
|
e79fdb |
(nextobj) - 1);
|
|
|
e79fdb |
g_object_unref (nextobj);
|
|
|
e79fdb |
+ nextobj = follow;
|
|
|
e79fdb |
}
|
|
|
e79fdb |
/* recurse with the last descendant */
|
|
|
e79fdb |
kount = sort_order_rev_canonical (mrp, ls, kount, max,
|
|
|
e79fdb |
nextobj, TRUE, pobj);
|
|
|
e79fdb |
+ if (nextobj)
|
|
|
e79fdb |
+ g_object_unref (nextobj);
|
|
|
e79fdb |
}
|
|
|
e79fdb |
else if (max == 0 || kount < max)
|
|
|
e79fdb |
{
|
|
|
e79fdb |
--
|
|
|
e79fdb |
2.9.3
|
|
|
e79fdb |
|