[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#779080: marked as done (unblock gtk+2.0/2.24.25-3)



Your message dated Thu, 05 Mar 2015 07:07:09 +0100
with message-id <54F7F28D.7050202@thykier.net>
and subject line Re: Bug#779080: unblock (pre-approval): gtk+2.0/2.24.25-2
has caused the Debian Bug report #779080,
regarding unblock gtk+2.0/2.24.25-3
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
779080: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779080
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please consider unblocking planned upload of package gtk+2.0.

+  * debian/patches/0001-Make-gdk_event_apply_filters-safe-against-changes-in.patch:
+    Cherry-pick patch from upstream stable branch to protect
+    gdk_event_apply_filters_safe from changes in the filter list (Closes:
+    #777142)

The MATE packaging team has discovered an issue in GTK-2 that is affecting several
GTK2 based applications inside Debian.

""" from #777142
A serious flaw in gdk_event_apply_filters function is causing weird crashes
in various software. For example, mate-display-properties crashes when
the screen resolution is changed or a new monitor is plugged in [1]. Some
other older bugs like [2] and [3] also might be caused by this one.
"""

In the upstream bug description (for GTK-3, please note this) [4], we find:

"""
If an event filter function calls gdk_window_add_filter or
gdk_window_remove_filter the list that gdk_event_apply_filters walks will
become inconsistent.

This may result in very obscure bugs and/or crashes.

An example of this problem may be found in gnome-desktop where a filter
is added to detect xrandr events and the callback calls a function that
adds and/or removes a filter in another class to monitor _NET_WORKSPACE
changes.  This results in a crash when adding a monitor.
"""

"""
An event filter may add or remove filters itself.  This patch does
two things to address this case.  The first is to take a temporary
reference to the filter while it is being used.  The second is
to wait until after the filter function is run before determining
the next node in the list to process.  This guards against
changes to the next node.  It also does not run functions
that have been marked as removed.  Though I'm not sure if this
case can arise.
"""

One of the MATE upstream devs sat down to backport that patch from GTK3
to GTK2 (which is already part of GTK2 2.24.26).

light+love,
Mike

[1] https://bugs.debian.org/760445
[2] https://bugs.debian.org/708559
[3] https://bugs.debian.org/718269
[4] https://bugzilla.gnome.org/show_bug.cgi?id=635380

unblock gtk+2.0/2.24.25-2

-- System Information:
Debian Release: 8.0
  APT prefers stable
  APT policy: (990, 'stable'), (500, 'testing-updates'), (500, 'testing-proposed-updates'), (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
diff -Nru gtk+2.0-2.24.25/debian/changelog gtk+2.0-2.24.25/debian/changelog
--- gtk+2.0-2.24.25/debian/changelog	2014-10-10 18:33:16.000000000 +0100
+++ gtk+2.0-2.24.25/debian/changelog	2015-02-23 17:51:40.000000000 +0000
@@ -1,3 +1,12 @@
+gtk+2.0 (2.24.25-2) UNRELEASED; urgency=medium
+
+  * debian/patches/0001-Make-gdk_event_apply_filters-safe-against-changes-in.patch:
+    Cherry-pick patch from upstream stable branch to protect
+    gdk_event_apply_filters_safe from changes in the filter list (Closes:
+    #777142)
+
+ -- Iain Lane <laney@debian.org>  Mon, 23 Feb 2015 17:46:25 +0000
+
 gtk+2.0 (2.24.25-1) unstable; urgency=medium
 
   * Team upload
diff -Nru gtk+2.0-2.24.25/debian/control gtk+2.0-2.24.25/debian/control
--- gtk+2.0-2.24.25/debian/control	2014-10-10 18:34:04.000000000 +0100
+++ gtk+2.0-2.24.25/debian/control	2015-02-23 17:51:45.000000000 +0000
@@ -2,7 +2,7 @@
 Section: libs
 Priority: optional
 Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
-Uploaders: Emilio Pozuelo Monfort <pochu@debian.org>, Iain Lane <laney@debian.org>, Michael Biebl <biebl@debian.org>
+Uploaders: Iain Lane <laney@debian.org>, Michael Biebl <biebl@debian.org>
 Build-Depends: debhelper (>= 8.1.3),
                gettext,
                gtk-doc-tools (>= 1.11),
diff -Nru gtk+2.0-2.24.25/debian/patches/0001-Make-gdk_event_apply_filters-safe-against-changes-in.patch gtk+2.0-2.24.25/debian/patches/0001-Make-gdk_event_apply_filters-safe-against-changes-in.patch
--- gtk+2.0-2.24.25/debian/patches/0001-Make-gdk_event_apply_filters-safe-against-changes-in.patch	1970-01-01 01:00:00.000000000 +0100
+++ gtk+2.0-2.24.25/debian/patches/0001-Make-gdk_event_apply_filters-safe-against-changes-in.patch	2015-02-23 17:45:41.000000000 +0000
@@ -0,0 +1,351 @@
+From ee95f3d7259c0859ce41189b781b4339b4cd64aa Mon Sep 17 00:00:00 2001
+From: Matthias Clasen <mclasen@redhat.com>
+Date: Fri, 13 Feb 2015 13:12:39 -0500
+Subject: [PATCH] Make gdk_event_apply_filters safe against changes in filter
+ list
+
+An event filter may add or remove filters itself. This patch does
+two things to address this case. The first is to take a temporary
+reference to the filter while it is being used. The second is
+to wait until after the filter function is run before determining
+the next node in the list to process. This guards against
+changes to the next node. It also does not run functions
+that have been marked as removed. Though I'm not sure if this
+case can arise.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=635380
+
+Backport of 323df2b2800383832ed3c2e43626f2c6821c33ec to
+the gtk-2-24 branch by Wolfgang Ulbrich.
+
+http://bugs.debian.org/777142
+---
+ gdk/gdkinternals.h            |  6 +++++
+ gdk/gdkwindow.c               | 30 +++++++++++++++--------
+ gdk/quartz/gdkevents-quartz.c | 55 ++++++++++++++++++++++++++++++-------------
+ gdk/win32/gdkevents-win32.c   | 37 ++++++++++++++++++++++-------
+ gdk/x11/gdkevents-x11.c       | 37 ++++++++++++++++++++++-------
+ 5 files changed, 122 insertions(+), 43 deletions(-)
+
+diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
+index 0bd803f..97a1daa 100644
+--- a/gdk/gdkinternals.h
++++ b/gdk/gdkinternals.h
+@@ -59,9 +59,15 @@ struct _GdkColorInfo
+   guint ref_count;
+ };
+ 
++typedef enum {
++  GDK_EVENT_FILTER_REMOVED = 1 << 0
++} GdkEventFilterFlags;
++
+ struct _GdkEventFilter {
+   GdkFilterFunc function;
+   gpointer data;
++  GdkEventFilterFlags flags;
++  guint ref_count;
+ };
+ 
+ struct _GdkClientFilter {
+diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
+index 45fee34..29c878f 100644
+--- a/gdk/gdkwindow.c
++++ b/gdk/gdkwindow.c
+@@ -2545,13 +2545,18 @@ gdk_window_add_filter (GdkWindow     *window,
+     {
+       filter = (GdkEventFilter *)tmp_list->data;
+       if ((filter->function == function) && (filter->data == data))
+-	return;
++        {
++          filter->ref_count++;
++          return;
++        }
+       tmp_list = tmp_list->next;
+     }
+ 
+   filter = g_new (GdkEventFilter, 1);
+   filter->function = function;
+   filter->data = data;
++  filter->ref_count = 1;
++  filter->flags = 0;
+ 
+   if (private)
+     private->filters = g_list_append (private->filters, filter);
+@@ -2593,16 +2598,21 @@ gdk_window_remove_filter (GdkWindow     *window,
+       tmp_list = tmp_list->next;
+ 
+       if ((filter->function == function) && (filter->data == data))
+-	{
+-	  if (private)
+-	    private->filters = g_list_remove_link (private->filters, node);
+-	  else
+-	    _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
+-	  g_list_free_1 (node);
+-	  g_free (filter);
++        {
++          filter->flags |= GDK_EVENT_FILTER_REMOVED;
++          filter->ref_count--;
++          if (filter->ref_count != 0)
++            return;
+ 
+-	  return;
+-	}
++          if (private)
++            private->filters = g_list_remove_link (private->filters, node);
++          else
++            _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
++          g_list_free_1 (node);
++          g_free (filter);
++
++          return;
++        }
+     }
+ }
+ 
+diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
+index 9e57edd..f199298 100644
+--- a/gdk/quartz/gdkevents-quartz.c
++++ b/gdk/quartz/gdkevents-quartz.c
+@@ -253,21 +253,42 @@ append_event (GdkEvent *event,
+ static gint
+ gdk_event_apply_filters (NSEvent *nsevent,
+ 			 GdkEvent *event,
+-			 GList *filters)
++			 GList **filters)
+ {
+   GList *tmp_list;
+   GdkFilterReturn result;
+   
+-  tmp_list = filters;
++  tmp_list = *filters;
+ 
+   while (tmp_list)
+     {
+       GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
+-      
+-      tmp_list = tmp_list->next;
++      GList *node;
++
++      if ((filter->flags & GDK_EVENT_FILTER_REMOVED) != 0)
++        {
++          tmp_list = tmp_list->next;
++          continue;
++        }
++
++      filter->ref_count++;
+       result = filter->function (nsevent, event, filter->data);
+-      if (result !=  GDK_FILTER_CONTINUE)
+-	return result;
++
++      /* get the next node after running the function since the
++         function may add or remove a next node */
++      node = tmp_list;
++      tmp_list = tmp_list->next;
++
++      filter->ref_count--;
++      if (filter->ref_count == 0)
++        {
++          *filters = g_list_remove_link (*filters, node);
++          g_list_free_1 (node);
++          g_free (filter);
++        }
++
++      if (result != GDK_FILTER_CONTINUE)
++        return result;
+     }
+ 
+   return GDK_FILTER_CONTINUE;
+@@ -1319,7 +1340,7 @@ gdk_event_translate (GdkEvent *event,
+       /* Apply global filters */
+       GdkFilterReturn result;
+ 
+-      result = gdk_event_apply_filters (nsevent, event, _gdk_default_filters);
++      result = gdk_event_apply_filters (nsevent, event, &_gdk_default_filters);
+       if (result != GDK_FILTER_CONTINUE)
+         {
+           return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+@@ -1390,19 +1411,19 @@ gdk_event_translate (GdkEvent *event,
+       GdkFilterReturn result;
+ 
+       if (filter_private->filters)
+-	{
+-	  g_object_ref (window);
++        {
++          g_object_ref (window);
+ 
+-	  result = gdk_event_apply_filters (nsevent, event, filter_private->filters);
++          result = gdk_event_apply_filters (nsevent, event, &filter_private->filters);
+ 
+-	  g_object_unref (window);
++          g_object_unref (window);
+ 
+-	  if (result != GDK_FILTER_CONTINUE)
+-	    {
+-	      return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+-	      goto done;
+-	    }
+-	}
++          if (result != GDK_FILTER_CONTINUE)
++            {
++              return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
++              goto done;
++            }
++        }
+     }
+ 
+   /* If the app is not active leave the event to AppKit so the window gets
+diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
+index 8b345cb..c853e1e 100644
+--- a/gdk/win32/gdkevents-win32.c
++++ b/gdk/win32/gdkevents-win32.c
+@@ -1069,7 +1069,7 @@ fill_key_event_string (GdkEvent *event)
+ static GdkFilterReturn
+ apply_event_filters (GdkWindow  *window,
+ 		     MSG        *msg,
+-		     GList      *filters)
++		     GList      **filters)
+ {
+   GdkFilterReturn result = GDK_FILTER_CONTINUE;
+   GdkEvent *event;
+@@ -1087,15 +1087,36 @@ apply_event_filters (GdkWindow  *window,
+    */
+   node = _gdk_event_queue_append (_gdk_display, event);
+   
+-  tmp_list = filters;
++  tmp_list = *filters;
+   while (tmp_list)
+     {
+       GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
+-      
+-      tmp_list = tmp_list->next;
++      GList *node;
++
++      if ((filter->flags & GDK_EVENT_FILTER_REMOVED) != 0)
++        {
++          tmp_list = tmp_list->next;
++          continue;
++        }
++
++      filter->ref_count++;
+       result = filter->function (msg, event, filter->data);
+-      if (result !=  GDK_FILTER_CONTINUE)
+-	break;
++
++      /* get the next node after running the function since the
++         function may add or remove a next node */
++      node = tmp_list;
++      tmp_list = tmp_list->next;
++
++      filter->ref_count--;
++      if (filter->ref_count == 0)
++        {
++          *filters = g_list_remove_link (*filters, node);
++          g_list_free_1 (node);
++          g_free (filter);
++        }
++
++      if (result != GDK_FILTER_CONTINUE)
++        break;
+     }
+ 
+   if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
+@@ -2075,7 +2096,7 @@ gdk_event_translate (MSG  *msg,
+     {
+       /* Apply global filters */
+ 
+-      GdkFilterReturn result = apply_event_filters (NULL, msg, _gdk_default_filters);
++      GdkFilterReturn result = apply_event_filters (NULL, msg, &_gdk_default_filters);
+       
+       /* If result is GDK_FILTER_CONTINUE, we continue as if nothing
+        * happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE,
+@@ -2121,7 +2142,7 @@ gdk_event_translate (MSG  *msg,
+     {
+       /* Apply per-window filters */
+ 
+-      GdkFilterReturn result = apply_event_filters (window, msg, ((GdkWindowObject *) window)->filters);
++      GdkFilterReturn result = apply_event_filters (window, msg, &((GdkWindowObject *) window)->filters);
+ 
+       if (result == GDK_FILTER_REMOVE || result == GDK_FILTER_TRANSLATE)
+ 	{
+diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
+index b96e9f5..8de98c5 100644
+--- a/gdk/x11/gdkevents-x11.c
++++ b/gdk/x11/gdkevents-x11.c
+@@ -96,7 +96,7 @@ struct _GdkEventTypeX11
+ 
+ static gint	 gdk_event_apply_filters (XEvent   *xevent,
+ 					  GdkEvent *event,
+-					  GList    *filters);
++					  GList    **filters);
+ static gboolean	 gdk_event_translate	 (GdkDisplay *display,
+ 					  GdkEvent   *event, 
+ 					  XEvent     *xevent,
+@@ -341,21 +341,42 @@ gdk_event_get_graphics_expose (GdkWindow *window)
+ static gint
+ gdk_event_apply_filters (XEvent *xevent,
+ 			 GdkEvent *event,
+-			 GList *filters)
++			 GList **filters)
+ {
+   GList *tmp_list;
+   GdkFilterReturn result;
+   
+-  tmp_list = filters;
++  tmp_list = *filters;
+   
+   while (tmp_list)
+     {
+       GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
++      GList *node;
+       
+-      tmp_list = tmp_list->next;
++      if ((filter->flags & GDK_EVENT_FILTER_REMOVED) != 0)
++        {
++          tmp_list = tmp_list->next;
++          continue;
++        }
++
++      filter->ref_count++;
+       result = filter->function (xevent, event, filter->data);
+-      if (result !=  GDK_FILTER_CONTINUE)
+-	return result;
++
++      /* get the next node after running the function since the
++         function may add or remove a next node */
++      node = tmp_list;
++      tmp_list = tmp_list->next;
++
++      filter->ref_count--;
++      if (filter->ref_count == 0)
++        {
++          *filters = g_list_remove_link (*filters, node);
++          g_list_free_1 (node);
++          g_free (filter);
++        }
++
++      if (result != GDK_FILTER_CONTINUE)
++        return result;
+     }
+   
+   return GDK_FILTER_CONTINUE;
+@@ -944,7 +965,7 @@ gdk_event_translate (GdkDisplay *display,
+       /* Apply global filters */
+       GdkFilterReturn result;
+       result = gdk_event_apply_filters (xevent, event,
+-                                        _gdk_default_filters);
++                                        &_gdk_default_filters);
+       
+       if (result != GDK_FILTER_CONTINUE)
+         {
+@@ -1050,7 +1071,7 @@ gdk_event_translate (GdkDisplay *display,
+ 	  g_object_ref (filter_window);
+ 	  
+ 	  result = gdk_event_apply_filters (xevent, event,
+-					    filter_private->filters);
++					    &filter_private->filters);
+ 	  
+ 	  g_object_unref (filter_window);
+       
+-- 
+2.1.4
+
diff -Nru gtk+2.0-2.24.25/debian/patches/series gtk+2.0-2.24.25/debian/patches/series
--- gtk+2.0-2.24.25/debian/patches/series	2014-08-10 13:47:58.000000000 +0100
+++ gtk+2.0-2.24.25/debian/patches/series	2015-02-23 17:45:00.000000000 +0000
@@ -1,3 +1,4 @@
+0001-Make-gdk_event_apply_filters-safe-against-changes-in.patch
 001_static-linking-dont-query-immodules.patch
 002_static-linking-dont-build-perf.patch
 003_gdk.pc_privates.patch

--- End Message ---
--- Begin Message ---
On 2015-03-05 05:06, Cyril Brulebois wrote:
> Control: tag -1 confirmed
> 
> Niels Thykier <niels@thykier.net> (2015-03-03):
>> On 2015-03-03 19:59, Iain Lane wrote:
>>> I backported these commits too. AFAIK it's good again (spotify works
>>> for me now anyway... I didn't know to blame the crashes on gtk
>>> before)
>>
>> Noted, I have updated my unblock hint and re-added the d-i tag.
> 
> netboot-gtk seems to still work fine with the updated gtk+ udebs, so no
> objections from me.
> 
> Mraw,
> KiBi.
> 

Added the -udeb unblock hint to match, thanks.

~Niels

--- End Message ---

Reply to: