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 733232 - rhythmbox crashes while using jamendo due to double free in libgrilo
rhythmbox crashes while using jamendo due to double free in libgrilo
Status: RESOLVED FIXED
Product: grilo
Classification: Other
Component: core
0.2.x
Other Linux
: Normal major
: ---
Assigned To: grilo-maint
grilo-maint
Depends on:
Blocks:
 
 
Reported: 2014-07-16 00:38 UTC by gnome.vrb
Modified: 2014-07-21 20:47 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch that fixes the crash (579 bytes, patch)
2014-07-16 09:00 UTC, gnome.vrb
none Details | Review
net: Fix invalid free (912 bytes, patch)
2014-07-16 10:37 UTC, Juan A. Suarez Romero
rejected Details | Review
net: Fix double-free using the Jamendo plugin (1.16 KB, patch)
2014-07-16 15:26 UTC, Bastien Nocera
committed Details | Review

Description gnome.vrb 2014-07-16 00:38:43 UTC
Steps to reproduce:

1. Go to jamendo tab in latest rhythmbox
2. Start clicking the "artist" / "album" / "feeds" at random.
3. Rhythmbox crashes with few seconds.

System information:

debian sid amd64

Package information:

ii  gir1.2-grilo-0.2                          0.2.10-1                          amd64        Framework for discovering and browsing media - GObject introspection data
ii  grilo-plugins-0.2:amd64                   0.2.12-4                          amd64        Framework for discovering and browsing media - Plugins
ii  grilo-plugins-0.2-dbg:amd64               0.2.12-4                          amd64        Framework for discovering and browsing media - Plugin debugging symbols
ii  libgrilo-0.2-1:amd64                      0.2.10-1                          amd64        Framework for discovering and browsing media - Shared libraries
ii  libgrilo-0.2-1-dbg:amd64                  0.2.10-1                          amd64        Framework for discovering and browsing media - debugging symbols
ii  libgrilo-0.2-dev                          0.2.10-1                          amd64        Framework for discovering and browsing media - Development files
Comment 1 gnome.vrb 2014-07-16 00:39:13 UTC
Backtrace:

Breakpoint 6, g_free (mem=0x1ce2d50) at /tmp/buildd/glib2.0-2.40.0/./glib/gmem.c:189
189	  if (G_LIKELY (mem))
  • #0 g_free
    at /tmp/buildd/glib2.0-2.40.0/./glib/gmem.c line 189
  • #1 grl_net_wc_flush_delayed_requests
    at grl-net-wc.c line 1134
  • #2 grl_jamendo_source_cancel
    at grl-jamendo.c line 1357
  • #3 start_browse
    at rb-grilo-source.c line 817
  • #4 expand_from_marker
    at rb-grilo-source.c line 1005
  • #5 browser_selection_changed_cb
    at rb-grilo-source.c line 1036
  • #6 _g_closure_invoke_va
    at /tmp/buildd/glib2.0-2.40.0/./gobject/gclosure.c line 831
  • #7 g_signal_emit_valist
    at /tmp/buildd/glib2.0-2.40.0/./gobject/gsignal.c line 3215
  • #8 g_signal_emit
    at /tmp/buildd/glib2.0-2.40.0/./gobject/gsignal.c line 3363
  • #9 ??
    from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
  • #10 ??
    from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
  • #11 ??
    from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
  • #12 _g_closure_invoke_va
    at /tmp/buildd/glib2.0-2.40.0/./gobject/gclosure.c line 831
  • #13 g_signal_emit_valist
    at /tmp/buildd/glib2.0-2.40.0/./gobject/gsignal.c line 3215
  • #14 g_signal_emit
    at /tmp/buildd/glib2.0-2.40.0/./gobject/gsignal.c line 3363
  • #15 ??
    from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
  • #16 ??
    from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
  • #17 gtk_main_do_event
    from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
  • #18 ??
    from /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
  • #19 g_main_dispatch
    at /tmp/buildd/glib2.0-2.40.0/./glib/gmain.c line 3064
  • #20 g_main_context_dispatch
    at /tmp/buildd/glib2.0-2.40.0/./glib/gmain.c line 3663
  • #21 g_main_context_iterate
    at /tmp/buildd/glib2.0-2.40.0/./glib/gmain.c line 3734
  • #22 g_main_context_iteration
    at /tmp/buildd/glib2.0-2.40.0/./glib/gmain.c line 3795
  • #23 g_application_run
    at /tmp/buildd/glib2.0-2.40.0/./gio/gapplication.c line 2114
  • #24 rb_application_run
    at rb-application.c line 646
  • #25 main
    at main.c line 89

Comment 2 gnome.vrb 2014-07-16 00:50:13 UTC
I spent some time looking into it. The below patch fixes the problem.

diff -r 2e134f2db3a7 libgrilo-0.2-1/grilo-0.2.10/libs/net/grl-net-wc.c
--- a/libgrilo-0.2-1/grilo-0.2.10/libs/net/grl-net-wc.c	Tue Jul 15 23:25:55 2014 +0530
+++ b/libgrilo-0.2-1/grilo-0.2.10/libs/net/grl-net-wc.c	Wed Jul 16 06:15:22 2014 +0530
@@ -1128,10 +1128,9 @@
   struct request_clos *c;
 
   while ((c = g_queue_pop_head (priv->pending))) {
+    if(c->cancellable)
+      g_object_unref (c->cancellable);
     g_source_remove (c->source_id);
-    g_object_unref (c->cancellable);
-    g_free (c->url);
-    g_free (c);
   }
 
   g_get_current_time (&priv->last_request);


Explanation of the fix:

1. The first call to g_free is called when g_source_remove is invoked, which calls the request_clos_destroy() callback, as part of the source destruction. This applies to both g_free cases in the code. Hence, both g_free() calls are removed.

2. GCancellable from the application could be NULL, and should be checked.

3. request_clos object 'c' is freed ( g_free(c) ) in request_close_destroy(), so g_object_unref(..) has to be called prior to g_source_remove()

I've manually tested this to work fine with rhythmbox.
Comment 3 Juan A. Suarez Romero 2014-07-16 08:56:20 UTC
Cool. Could you upload a patch with the changes? If you can't I can do it on your behalf.
Comment 4 gnome.vrb 2014-07-16 09:00:19 UTC
Created attachment 280779 [details] [review]
Patch that fixes the crash
Comment 5 Juan A. Suarez Romero 2014-07-16 10:37:14 UTC
Created attachment 280785 [details] [review]
net: Fix invalid free

https://bugzilla.gnome.org/show_bug.cgi?id=733232

Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Comment 6 Bastien Nocera 2014-07-16 13:07:29 UTC
Review of attachment 280785 [details] [review]:

This looks incorrect.

::: libs/net/grl-net-wc.c
@@ -1131,3 @@
     g_source_remove (c->source_id);
-    g_object_unref (c->cancellable);
-    g_free (c->url);

You'd be leaking the URL, and the struct itself.

Use g_clear_object() and g_clear_pointer() instead?
Comment 7 Bastien Nocera 2014-07-16 13:10:04 UTC
Review of attachment 280785 [details] [review]:

::: libs/net/grl-net-wc.c
@@ +1130,2 @@
   while ((c = g_queue_pop_head (priv->pending))) {
+    g_clear_object (&c->cancellable);

In fact, the cancellable shouldn't be unref'ed. We don't own a single reference to it:
 775   c->cancellable = cancellable;•

This code should probably cancel the cancellable though.
Comment 8 Juan A. Suarez Romero 2014-07-16 13:42:52 UTC
(In reply to comment #6)
> Review of attachment 280785 [details] [review]:
> 
> This looks incorrect.
> 
> ::: libs/net/grl-net-wc.c
> @@ -1131,3 @@
>      g_source_remove (c->source_id);
> -    g_object_unref (c->cancellable);
> -    g_free (c->url);
> 
> You'd be leaking the URL, and the struct itself.
> 

Not sure, see comment #2.

For each request_clos we create a g_idle function, with request_close_destroy() destructor that frees the url and the struct itself. The id of the g_idle function is stored in c->source_id. So I assume that g_source_remove() will trigger the destructor. Am I correct?
Comment 9 Juan A. Suarez Romero 2014-07-16 13:44:54 UTC
(In reply to comment #7)
> In fact, the cancellable shouldn't be unref'ed. We don't own a single reference
> to it:
>  775   c->cancellable = cancellable;•
> 
> This code should probably cancel the cancellable though.

Right.
Comment 10 Bastien Nocera 2014-07-16 15:26:12 UTC
Created attachment 280851 [details] [review]
net: Fix double-free using the Jamendo plugin

The item in the queue is already freed when the source is removed,
through a destroy notify, so no need to do it twice.

Ensure we cancel the cancellable though, but do not unref it as we do
not own it.