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 776147 - gio/glocalfilemonitor.c doesn't handle case G_FILE_MONITOR_EVENT_MOVED, crashing many programs.
gio/glocalfilemonitor.c doesn't handle case G_FILE_MONITOR_EVENT_MOVED, crash...
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gio
unspecified
Other All
: Normal major
: ---
Assigned To: gtkdev
gtkdev
: 790148 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2016-12-15 18:58 UTC by Aaron Franke
Modified: 2019-07-15 02:51 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
kqueue: Fix invalid emission of G_FILE_MONITOR_EVENT_MOVED event (1.59 KB, patch)
2017-11-10 15:12 UTC, Philip Withnall
none Details | Review
kqueue: Fix invalid emission of G_FILE_MONITOR_EVENT_MOVED event (1.59 KB, patch)
2017-11-24 20:04 UTC, Philip Withnall
committed Details | Review
inotify: Ignore IN_Q_OVERFLOW events (1.28 KB, patch)
2017-11-24 20:04 UTC, Philip Withnall
committed Details | Review
inotify: Don’t propagate unrecognised events to GLocalFileMonitor (2.83 KB, patch)
2017-11-24 20:04 UTC, Philip Withnall
committed Details | Review

Description Aaron Franke 2016-12-15 18:58:19 UTC
Line 430 of gio/glocalfilemonitor.c doesn't handle case G_FILE_MONITOR_EVENT_MOVED, crashing many programs. 

The list of programs affected includes but is not limited to: 

xfdesktop https://bugs.launchpad.net/ubuntu/+source/xfdesktop4/+bug/1598360 

pcmanfm https://bugs.launchpad.net/ubuntu/+source/pcmanfm/+bug/1598488 

and caja https://bugs.launchpad.net/ubuntu/+source/caja/+bug/1598359

The affected code can be found at https://github.com/GNOME/glib/blob/master/gio/glocalfilemonitor.c and looks like this:

  switch (event_type)
    {
    
    (other conditions are located here)
    
    case G_FILE_MONITOR_EVENT_MOVED:
      /* was never available in this API */
    default:
      g_assert_not_reached ();
    }

This matches with the g_assertion_message() crash that these programs are experiencing. So, I think we've found the culprit, and the solution would be to do something to handle case G_FILE_MONITOR_EVENT_MOVED so that these programs do not crash. Alternatively, if this API function should never be used, then the maintainers of these programs should be notified of this easily reproducible bug and be shown how to fix it. Right now, many packages that come default on major distros such as Ubuntu flavors are completely broken.
Comment 1 Philip Withnall 2017-11-10 01:22:55 UTC
*** Bug 790148 has been marked as a duplicate of this bug. ***
Comment 2 Robert 2017-11-10 01:35:07 UTC
Why not to move:
case G_FILE_MONITOR_EVENT_MOVED:

under:
case G_FILE_MONITOR_EVENT_RENAMED:

so they will handle same way (because they are *almost* same right?). G_FILE_MONITOR_EVENT_RENAMED branch even operates with names like "G_FILE_MONITOR_WATCH_MOVES" and "G_FILE_MONITOR_SEND_MOVED" internally.

Apparently "was never available in this API" is not true because of the list of affected apps.
Comment 3 Philip Withnall 2017-11-10 15:12:26 UTC
Created attachment 363349 [details] [review]
kqueue: Fix invalid emission of G_FILE_MONITOR_EVENT_MOVED event

That event is deprecated, and the kqueue backend can’t provide enough
information to go alongside the event (i.e. the name of the new file).
Use G_FILE_MONITOR_EVENT_DELETED instead.

Quite disappointed in the kqueue documentation for this: I cannot find a
single piece of documentation or example about how NOTE_RENAME is
supposed to communicate the new name of the file.

If it turns out that this is possible, the code can be amended again in
future. At least now it doesn’t abort.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
Comment 4 Philip Withnall 2017-11-10 15:29:14 UTC
(In reply to Robert from comment #2)
> Why not to move:
> case G_FILE_MONITOR_EVENT_MOVED:
> 
> under:
> case G_FILE_MONITOR_EVENT_RENAMED:
> 
> so they will handle same way (because they are *almost* same right?).
> G_FILE_MONITOR_EVENT_RENAMED branch even operates with names like
> "G_FILE_MONITOR_WATCH_MOVES" and "G_FILE_MONITOR_SEND_MOVED" internally.

Because that would be fixing the symptom of the problem, rather than the underlying cause. This problem hasn’t been fixed already because nobody’s found time to investigate it yet.

> Apparently "was never available in this API" is not true because of the list
> of affected apps.

I just spent a bit of time looking into it, and it seems this is caused by the kqueue backend sending through an invalid event. I’ve attached a patch for that.

If you weren’t using FreeBSD (or another system which uses kqueue, like OS X), please let me know. There’s a potential bug in the inotify backend where a -1 return value from ih_mask_to_EventFlags() can be passed through to g_file_monitor_source_handle_event(), but I’m not 100% sure that’s possible due to other checks beforehand.
Comment 5 Robert 2017-11-10 15:49:29 UTC
Hm, I though this ticket was initially regarding Linux distros (there was an Ubuntu mentioned in the initial description), I doubt it was an Ubuntu based on BSD kernel, it's very rare...
Thanks for the fix!
Comment 6 Aaron Franke 2017-11-10 19:36:05 UTC
The bugs occur for me on Xubuntu 16.04 LTS, which is Linux. If this patch is only for BSD and OSX then it won't solve the problem on Linux.

I do think it's strange that programs would use it if it was never available.
Comment 7 Robert 2017-11-10 19:41:13 UTC
With all that said, I would revert subject back to what it was (unrelated to kqueue), and extend affected OSes list.
Comment 8 Philip Withnall 2017-11-11 23:40:13 UTC
Right.

Here’s an actual backtrace from a Linux system, retrieved from Launchpad: https://launchpadlibrarian.net/217269912/Stacktrace.txt. I’ll try and find time to take a look at this next week, but given that the inotify event details are not in the backtrace, any fix I come up with is going to be an educated guess.

  • #0 __GI_raise
    at ../sysdeps/unix/sysv/linux/raise.c line 55
  • #1 __GI_abort
    at abort.c line 89
  • #2 g_assertion_message
    at /build/glib2.0-hcw3A1/glib2.0-2.45.7/./glib/gtestutils.c line 2429
  • #3 g_assertion_message_expr
    at /build/glib2.0-hcw3A1/glib2.0-2.45.7/./glib/gtestutils.c line 2444
  • #4 g_file_monitor_source_handle_event
    at /build/glib2.0-hcw3A1/glib2.0-2.45.7/./gio/glocalfilemonitor.c line 433
  • #5 ih_event_callback
    at /build/glib2.0-hcw3A1/glib2.0-2.45.7/./gio/inotify/inotify-helper.c line 201
  • #6 ip_event_dispatch
    at /build/glib2.0-hcw3A1/glib2.0-2.45.7/./gio/inotify/inotify-path.c line 493
  • #7 ip_event_callback
    at /build/glib2.0-hcw3A1/glib2.0-2.45.7/./gio/inotify/inotify-path.c line 547

Comment 9 Philip Withnall 2017-11-24 20:00:25 UTC
From that backtrace:

  • #4 g_file_monitor_source_handle_event

I don’t think there’s much we can do to recover from events being dropped as a result of queue overflow. But we can at least not assert in that case.

Patches coming shortly. I can’t think of a decent way of producing a reliable unit test for this, although I would really like to. inotify events are pulled off the inotify FD in a GLib worker thread, and we have no control over that worker thread — I can’t think of a way to suspend it, cancel and restart it, or otherwise cause it to not read the FD for long enough for a load of events to queue up. This is probably only replicable using a highly contested main context with a lot of inotify watches and events; and that can’t reliably be turned into a test. :-(
Comment 10 Philip Withnall 2017-11-24 20:04:48 UTC
Created attachment 364356 [details] [review]
kqueue: Fix invalid emission of G_FILE_MONITOR_EVENT_MOVED event

That event is deprecated, and the kqueue backend can’t provide enough
information to go alongside the event (i.e. the name of the new file).
Use G_FILE_MONITOR_EVENT_DELETED instead.

Quite disappointed in the kqueue documentation for this: I cannot find a
single piece of documentation or example about how NOTE_RENAME is
supposed to communicate the new name of the file.

If it turns out that this is possible, the code can be amended again in
future. At least now it doesn’t abort.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
Comment 11 Philip Withnall 2017-11-24 20:04:53 UTC
Created attachment 364357 [details] [review]
inotify: Ignore IN_Q_OVERFLOW events

There’s not much we can do about them, and if they go unhandled, they
can propagate through to g_file_monitor_source_handle_event() and cause
assertion failures due to not mapping to a GFileMonitorEvent.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
Comment 12 Philip Withnall 2017-11-24 20:04:59 UTC
Created attachment 364358 [details] [review]
inotify: Don’t propagate unrecognised events to GLocalFileMonitor

If we can’t convert the inotify event mask into a GFileMonitorEvent enum
value, don’t propagate it to GLocalFileMonitor, since it hits an
assertion failure in that case.

This should no longer be possible since the previous commit to ignore
IN_Q_OVERFLOW events, but we might as well change this just in case
other bugs crop up in event mask handling.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
Comment 13 Emmanuele Bassi (:ebassi) 2017-11-28 13:37:27 UTC
Review of attachment 364356 [details] [review]:

Looks reasonable.
Comment 14 Emmanuele Bassi (:ebassi) 2017-11-28 13:37:53 UTC
Review of attachment 364357 [details] [review]:

Okay
Comment 15 Emmanuele Bassi (:ebassi) 2017-11-28 13:39:05 UTC
Review of attachment 364358 [details] [review]:

Okay
Comment 16 Philip Withnall 2017-11-28 13:56:20 UTC
Great, thanks for the reviews.

Attachment 364356 [details] pushed as 76072a2 - kqueue: Fix invalid emission of G_FILE_MONITOR_EVENT_MOVED event
Attachment 364357 [details] pushed as 9853842 - inotify: Ignore IN_Q_OVERFLOW events
Attachment 364358 [details] pushed as 748bb24 - inotify: Don’t propagate unrecognised events to GLocalFileMonitor
Comment 17 Philip Withnall 2017-11-28 13:57:42 UTC
Also backported to glib-2-54:

3246f1df9 inotify: Don’t propagate unrecognised events to GLocalFileMonitor
d97e07709 inotify: Ignore IN_Q_OVERFLOW events
38ec9c6da kqueue: Fix invalid emission of G_FILE_MONITOR_EVENT_MOVED event
Comment 18 Aaron Franke 2019-07-15 02:51:12 UTC
Non-backported fix is available in glib version 2.56.