Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libportal should treat file URIs as paths inside the sandbox namespace #31

Open
Vanadiae opened this issue Jun 9, 2020 · 12 comments
Open

Comments

@Vanadiae
Copy link

Vanadiae commented Jun 9, 2020

We can pass multiple types of uri parameter to xdp_portal_set_wallpaper:

  1. an URL to a location on internet. for example https://avatars2.githubusercontent.com/u/48521955?s=60&v=4 which is my avatar icon. This works.
  2. a file:/// URI of a file available inside the sandbox

However, the third point doesn't work. If I pass a file:/// URI, it thinks it is outside the sandbox and doesn't find it and if I pass a filename (/tmp/app111/image.png), there is the loading spinner forever but the image can't be set as wallpaper nor does it appear in the preview window.

This is reproducable by applying this patch to a clean master tree (with the path changed to an image installed in the sandbox) and run PortalTest:

diff --git a/portal-test/portal-test-win.c b/portal-test/portal-test-win.c
index 9f07b38..bd0ec8e 100644
--- a/portal-test/portal-test-win.c
+++ b/portal-test/portal-test-win.c
@@ -1161,8 +1161,10 @@ static void
 set_wallpaper (PortalTestWin *win)
 {
   XdpParent *parent;
-//  const char *uri = "https://gitlab.gnome.org/GNOME/gtk/raw/master/demos/gtk-demo/portland-rose.jpg";
-  const char *uri = "file:///usr/share/backgrounds/gnome/adwaita-morning.jpg";
+  /* const char *uri = "https://gitlab.gnome.org/GNOME/gtk/raw/master/demos/gtk-demo/portland-rose.jpg"; */
+  /* const char *uri = "file:///usr/share/backgrounds/gnome/adwaita-morning.jpg"; */
+  const char *uri = "file:///my_path/in_sandbox/to_the/image.png";
+  g_assert (g_file_test (uri, G_FILE_TEST_EXISTS));
 
   parent = xdp_parent_new_gtk (GTK_WINDOW (win));
   xdp_portal_set_wallpaper (win->portal,

This currently blocks my MR for GNOME Web for the time being.

I hope it can be fixed.

Edited to clarify, following mcatanzaro message.

@mcatanzaro
Copy link

  • an URL to a location on internet. for example https://avatars2.githubusercontent.com/u/48521955?s=60&v=4 which is my avatar icon.
  • a file:/// URI of a file available outside the sandbox. for example file:///home/user/Downloads/my_image.png.
  • a file available only inside the running flatpak sandbox. For example, the application might download an image to a temporary directory then pass it to set_wallpaper.

Hmm, I don't think the second point makes sense, because applications do not have access to paths outside the sandbox, so how would an application ever successfully pass such a path? It doesn't make sense. So I would rephrase this bug report as: "libportal should treat file URIs as paths inside the sandbox namespace." In the case of /usr/share, that's going to be mounted in the sandbox, so it should work out the same.

@Vanadiae
Copy link
Author

I agree with you that a file:/// URI should point in the sandbox, not outside. This is however how it reacts for now.

In the case of /usr/share, that's going to be mounted in the sandbox, so it should work out the same.

I used a path in /usr/share to not have to install an image in the sandbox in meson.build (but this works with anything in the sandbox as you understanded). But the point is about all files in the sandbox. So I'll rephrase the title and clarify the original post to be clearer.

@Vanadiae Vanadiae changed the title Can't set wallpaper with sandbox-only accessible image libportal should treat file URIs as paths inside the sandbox namespace Jun 10, 2020
@Vanadiae
Copy link
Author

it seems that the problem is in xdg-desktop-portal as it crashes when I pass a file:/// URI (but this issue shouldn't be closed for the moment as it might as well be libportal's fault). The errors printed are

** (/usr/libexec/xdg-desktop-portal:13723): DEBUG: 21:37:33.265: No 'wallpaper' permissions found: No entry for wallpaper

(/usr/libexec/xdg-desktop-portal:13723): GLib-CRITICAL **: 21:37:33.265: g_variant_get_type: assertion 'value != NULL' failed

(/usr/libexec/xdg-desktop-portal:13723): GLib-CRITICAL **: 21:37:33.265: g_variant_type_is_subtype_of: assertion 'g_variant_type_check (type)' failed

(/usr/libexec/xdg-desktop-portal:13723): GLib-CRITICAL **: 21:37:33.265: g_variant_get_type_string: assertion 'value != NULL' failed

(/usr/libexec/xdg-desktop-portal:13723): GLib-ERROR **: 21:37:33.265: g_variant_new: expected GVariant of type 'a{sv}' but received value has type '(null)'

Thread 11 "pool-/usr/libex" received signal SIGTRAP, Trace/breakpoint trap.

I will debug and obtain a full backtrace from gdb.

@Vanadiae
Copy link
Author

Vanadiae commented Jun 19, 2020

The full backtrace of the crash is as follow.

#0  g_log_structured_array (log_level=<optimized out>, fields=0x7fffe3ffe160, n_fields=4) at ../glib/gmessages.c:554
        writer_func = <optimized out>
        writer_user_data = <optimized out>
        recursion = <optimized out>
        depth = <optimized out>
        __func__ = "g_log_structured_array"
        _g_boolean_var_ = <optimized out>
#1  0x00007ffff7bddd69 in g_log_default_handler (log_domain=log_domain@entry=0x7ffff7c2600e "GLib", log_level=log_level@entry=6, 
    message=message@entry=0x7fffdc016ef0 "g_variant_new: expected GVariant of type 'a{sv}' but received value has type '(null)'", unused_data=unused_data@entry=0x0) at ../glib/gmessages.c:3123
        fields = {{key = 0x7ffff7c306a6 "GLIB_OLD_LOG_API", value = 0x7ffff7c8993c, length = -1}, {key = 0x7ffff7c305d0 "MESSAGE", value = 0x7fffdc016ef0, length = -1}, {
            key = 0x7ffff7c305e3 "PRIORITY", value = 0x7ffff7c304a2, length = -1}, {key = 0x7ffff7c3063d "GLIB_DOMAIN", value = 0x7ffff7c2600e, length = -1}}
        n_fields = <optimized out>
#2  0x00007ffff7bddfb9 in g_logv (log_domain=0x7ffff7c2600e "GLib", log_level=G_LOG_LEVEL_ERROR, format=<optimized out>, args=<optimized out>) at ../glib/gmessages.c:1350
        domain = 0x0
        data = 0x0
        depth = <optimized out>
        log_func = 0x7ffff7bddcb0 <g_log_default_handler>
        domain_fatal_mask = <optimized out>
        masquerade_fatal = 0
        test_level = 6
        was_fatal = <optimized out>
        was_recursion = <optimized out>
        buffer = <optimized out>
        msg = 0x7fffdc016ef0 "g_variant_new: expected GVariant of type 'a{sv}' but received value has type '(null)'"
        msg_alloc = 0x7fffdc016ef0 "g_variant_new: expected GVariant of type 'a{sv}' but received value has type '(null)'"
        i = 2
        size = <optimized out>
#3  0x00007ffff7bde253 in g_log (log_domain=log_domain@entry=0x7ffff7c2600e "GLib", log_level=log_level@entry=G_LOG_LEVEL_ERROR, 
    format=format@entry=0x7ffff7c87760 "g_variant_new: expected GVariant of type '%s' but received value has type '%s'") at ../glib/gmessages.c:1415
        args = {{gp_offset = 40, fp_offset = 48, overflow_arg_area = 0x7fffe3ffe380, reg_save_area = 0x7fffe3ffe2c0}}
#4  0x00007ffff7c13aec in g_variant_valist_new_nnp (str=<optimized out>, ptr=0x0) at ../glib/gvariant.c:4830
        type_string = 0x7fffd800f620 "a{sv}"
        __func__ = "g_variant_valist_new_nnp"
#5  0x00007ffff7c14eff in g_variant_valist_new_leaf (app=<optimized out>, str=<optimized out>) at ../glib/gvariant.c:4987
        __func__ = "g_variant_valist_new_leaf"
#6  g_variant_valist_new (str=<optimized out>, app=<optimized out>) at ../glib/gvariant.c:5169
        __func__ = "g_variant_valist_new"
#7  0x0000000000000001 in ?? ()
No symbol table info available.
#8  0x0000000000000000 in ?? ()
No symbol table info available.

I couldn't manage to know the symbol names of the two last ones (even after having installed every debuginfo package that appeared as "missing").

This is the what I could find by running xdg-desktop-portal with gdb. In src/wallpaper.c of xdg-desktop-portal, function handle_set_wallpaper_in_thread_func, when the SetWallpaperFile is called (i.e. using the file:/// uri scheme in libportal), I printed the fd variable which was 24 in my case. So looking to /proc//fd/, the file designated by this path is the image that I passed in epiphany (which links to /tmp/epiphany-XXXXXXX/<image_basename>) which means that the problem is not in libportal (it could in fact, if it doesn't use the correct flag to open then pass the fd) nor the code in epiphany but in xdp (xdg-desktop-portal). So in the function previously cited, the code enter in the if (!uri) block which is what is expected since I didn't pass the URI but a fd. But then the program runs in the if (path == NULL) block and so rejects the request. That's why the wallpaper previewer doesn't show up, because xdp rejects the request. This means xdp_app_info_get_path_for_fd returns NULL. So stepping through this function, the path is correctly found (the /tmp/epiphany-XXXXX/<image_basename> previously cited) with the fd that libportal passed. Function xdp_app_info_get_path_for_fd then enters in function stat (at the end of the function, if (stat (path, &real_st_buf) < 0 ||) and this function is the culprit. It filled "errno" so it's possible to know what went wrong. The message corresponding to the errno is "No such file or directory" but then I don't understand why since it could find the appropriate path for the fd that libportal provides. By the way, libportal opens the wallpaper image with flags O_CLOEXEC and O_PATH. I wasn't able to know why it doesn't work, though I could analyze how it runs on xdp's side (and this made me use gdb for the first real time (i.e. not just run but break, next, step, jump)).

@mcatanzaro
Copy link

I've added this to my TODO to investigate.

@Vanadiae
Copy link
Author

Thanks ;) (trying) to debug was quite fun actually (though I couldn't fix this) :D

@Vanadiae
Copy link
Author

Had you any time to look at this (no hurry, just so epiphany's MR can be merged) ?

@mcatanzaro
Copy link

Nope, still on my TODO, sorry.

@Vanadiae
Copy link
Author

Vanadiae commented Aug 3, 2020

this might get fixed by flatpak/xdg-desktop-portal#515, as it touches how fd and uri are handled (and closed). Let's see once it's merged.

@mcatanzaro
Copy link

I haven't looked at flatpak/xdg-desktop-portal#515, just wanted to mention this is still on my TODO.

@Vanadiae
Copy link
Author

I'm looking into this. The problem isn't xdg-desktop-portal, but libportal, because an other wrapper around the dbus api (in rust, ashpd) works on my side. Will look into it.

@mcatanzaro
Copy link

So in https://gitlab.gnome.org/GNOME/epiphany/-/merge_requests/673#note_925875 we determined that I am not able to reproduce this. We don't know why, but one difference is that I have upgraded to F33 while Vanadiae is still on F32. It's optimistic, but if we're lucky, maybe this fixed itself somehow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants