Blame SOURCES/0001-Fix-use-after-free-when-returned-objects-hold-only-o.patch

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