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 692408 - nautilus SIGSEGV in g_file_info_get_size()
nautilus SIGSEGV in g_file_info_get_size()
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gio
2.35.x
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2013-01-23 18:09 UTC by Sebastien Bacher
Modified: 2013-01-28 15:39 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
0001-GFile-Clean-up-file_copy_fallback-to-fix-SEGV-with-b.patch (7.99 KB, patch)
2013-01-25 15:43 UTC, Colin Walters
reviewed Details | Review
0001-GFile-Clean-up-file_copy_fallback-to-fix-SEGV-with-b.patch (7.13 KB, patch)
2013-01-25 18:42 UTC, Colin Walters
committed Details | Review

Description Sebastien Bacher 2013-01-23 18:09:07 UTC
Since glib was updated in Ubuntu from 2.34 to 2.35.4 we started receiving nautilus segfaults similar to 

https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/1102164

"#0  0x00007f05fa2d0966 in g_file_info_get_size (info=info@entry=0x1fe0ca0) at /build/buildd/glib2.0-2.35.4/./gio/gfileinfo.c:1733
        __inst = 0x1fe0ca0
        __t = 139663075453920
        __r = <optimized out>
        _g_boolean_var_ = <optimized out>
        attr = 1048590
        value = <optimized out>
        __PRETTY_FUNCTION__ = "g_file_info_get_size"
  • #1 btrfs_reflink_with_progress
    at /build/buildd/glib2.0-2.35.4/./gio/gfile.c line 2937
  • #2 file_copy_fallback
    at /build/buildd/glib2.0-2.35.4/./gio/gfile.c line 3062
  • #3 g_file_copy
    at /build/buildd/glib2.0-2.35.4/./gio/gfile.c line 3242
  • #4 copy_move_file
    at nautilus-file-operations.c line 4307
  • #5 copy_move_directory
    at nautilus-file-operations.c line 3666
  • #6 copy_move_file
    at nautilus-file-operations.c line 4517
  • #7 copy_move_directory
    at nautilus-file-operations.c line 3666
  • #8 copy_move_file
    at nautilus-file-operations.c line 4517
  • #9 copy_files
    at nautilus-file-operations.c line 4636
  • #10 copy_job
    at nautilus-file-operations.c line 4748
  • #11 io_job_thread
    at /build/buildd/glib2.0-2.35.4/./gio/gioscheduler.c line 89
  • #12 g_task_thread_pool_thread
    at /build/buildd/glib2.0-2.35.4/./gio/gtask.c line 1242
  • #13 g_thread_pool_thread_proxy
    at /build/buildd/glib2.0-2.35.4/./glib/gthreadpool.c line 309
  • #14 g_thread_proxy
    at /build/buildd/glib2.0-2.35.4/./glib/gthread.c line 798
  • #15 start_thread
    at pthread_create.c line 311
  • #16 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 114
..."

That seems likely a side effect of
http://git.gnome.org/browse/glib/commit/?id=5eba9784979e0b723c05a45cf767046607e4e759
"GFile: Add Btrfs clone ioctl support"

One of those bugs mention the issue happened while copying a folder to an usb key
Comment 1 Colin Walters 2013-01-23 18:15:22 UTC
Looks to me it's because we unref the info here;

  /* Everything else should just fall back on a regular copy. */
  else
    g_object_unref (info);

...

then:

      result = btrfs_reflink_with_progress (in, out, info, cancellable,

But info is freed.  Needs some refactoring to preserve info until at least that point.  I suggest changing the function to "goto out" style with cleanups at the end.
Comment 2 Colin Walters 2013-01-25 15:43:59 UTC
Created attachment 234419 [details] [review]
0001-GFile-Clean-up-file_copy_fallback-to-fix-SEGV-with-b.patch
Comment 3 Dan Winship 2013-01-25 16:13:51 UTC
Comment on attachment 234419 [details] [review]
0001-GFile-Clean-up-file_copy_fallback-to-fix-SEGV-with-b.patch

>+  if (!out)
>+    goto out;

Ick.

> #ifdef HAVE_SYS_IOCTL_H
>-  if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))
>+  if (!did_optimized_copy && G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))

did_optimized_copy can't actually be TRUE here. (And if you're thinking "well maybe we'll add another case before this one later", the flip side of that is that clang and coverity will probably complain about it.)

And anyway, I think it was clearer with the gotos than with the if !did_optimized_copy. If you had each of the the three copying cases do "ret = TRUE; goto out;" if they succeeded, then you could move the final g_file_copy_attributes() to after out:, but only calling it if ret==TRUE (and then you don't need to call it from copy_symlink()).
Comment 4 Colin Walters 2013-01-25 18:42:55 UTC
Created attachment 234434 [details] [review]
0001-GFile-Clean-up-file_copy_fallback-to-fix-SEGV-with-b.patch

Yeah, maybe in this case it's slightly clearer.
Comment 5 Nirbheek Chauhan 2013-01-26 03:57:42 UTC
(In reply to comment #4)
> Created an attachment (id=234434) [details] [review]
> 0001-GFile-Clean-up-file_copy_fallback-to-fix-SEGV-with-b.patch
> 

I can't find anything wrong with the patch itself (and it passes make check for me). However, maybe we should add a test for this problem to gfile? The old code didn't trigger any test failures either.

Also, a little nitpick: personally, I think two labels, "err" and "out" would be clearer than one label "out" + ret = FALSE/TRUE. That makes it clear to anyone reading the code whether the premature exit is a failure condition or not. So, something like:

[…]
out:
  /* Ignore errors here. Failure to copy metadata is not a hard error */
  (void) g_file_copy_attributes (source, destination,
                                 flags, cancellable, NULL);

  ret = TRUE;
err:
  if (in)
    {
      /* Don't care about errors in source here */
      (void) g_input_stream_close (in, cancellable, NULL);
      g_object_unref (in);
    }
[…]

And then, replace "ret = TRUE; goto out;" with "goto out;", and plain "goto out;" with "goto err;". But this is just my opinion. :)
Comment 6 Dan Winship 2013-01-27 16:03:32 UTC
Comment on attachment 234434 [details] [review]
0001-GFile-Clean-up-file_copy_fallback-to-fix-SEGV-with-b.patch

yeah, works for me

(In reply to comment #5)
> I can't find anything wrong with the patch itself (and it passes make check for
> me). However, maybe we should add a test for this problem to gfile? The old
> code didn't trigger any test failures either.

You can only test it if you have a btrfs file system though...
Comment 7 Nirbheek Chauhan 2013-01-28 15:39:45 UTC
> (In reply to comment #5)
> > I can't find anything wrong with the patch itself (and it passes make check for
> > me). However, maybe we should add a test for this problem to gfile? The old
> > code didn't trigger any test failures either.
> 
> You can only test it if you have a btrfs file system though...

That's the thing. I did run the gfile tests on a btrfs filesystem in the original bug 626497, and they all passed. You can try this yourself by loopback-mounting a btrfs filesystem, and running `gio/tests/live-g-file` inside it.