After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 635380 - gdk_event_apply_filters is unsafe against changes in filter list
gdk_event_apply_filters is unsafe against changes in filter list
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: X11
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2010-11-20 20:41 UTC by William Jon McCann
Modified: 2010-11-22 18:20 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Make gdk_event_apply_filters safe against changes in filter list (8.65 KB, patch)
2010-11-20 23:08 UTC, William Jon McCann
committed Details | Review

Description William Jon McCann 2010-11-20 20:41:40 UTC
If a 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.
Comment 1 Owen Taylor 2010-11-20 20:53:51 UTC
Based on some IRC comments I made:

GDK event filters have lasted as low tech for a long time ... I don't know if more complexity is actually needed. They are a bit hacky in the first place.

But basically, we have the know-how to create massively safe-against-reentrancy hook-list invocation ... eg., GSignal or GMainContext. It's not as simple as copying the list - that doesn't work - usually it's done by embedding a reference count on the node and temporarily increasing that as you walk the list and only removing nodes when the refcount drops to 0. And also having a removed bitflag so if you recurse - which is certainly evil from a event filter but not entirely impossible you don't invoke filters you've already removed.

What I wouldn't suggest is using GHookList. My experiences with it indicate that it's harder to figure out how to use it or read the resulting code than it is to code things correctly from scratch.
Comment 2 William Jon McCann 2010-11-20 23:08:08 UTC
Created attachment 174928 [details] [review]
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.
Comment 3 Matthias Clasen 2010-11-22 17:50:44 UTC
Review of attachment 174928 [details] [review]:

Looks right to me.

::: gdk/x11/gdkeventsource.c
@@ +76,3 @@
+        }
+
+      node = tmp_list;

Might be better to move the node assignment above the tmp_list assignment. I almost overlooked the purpose of node further down...
Comment 4 William Jon McCann 2010-11-22 18:19:47 UTC
Pushed with that change and fixed a typo in win32.

commit 323df2b2800383832ed3c2e43626f2c6821c33ec