RFC: libei - emulated input in Wayland compositors

Peter Hutterer peter.hutterer at who-t.net
Mon Aug 3 04:57:11 UTC 2020

On Sat, Aug 01, 2020 at 01:42:16PM +0200, Roman Gilg wrote:
> >
> > 1) It exports a set of APIs under org.freedesktop.portal.* that all
> > sandboxed applications can access.
> >
> > In contrast to explicitly allowed APIs (i.e. build time configured list
> > of API to be exposed directly to inside an application sandbox by
> > default), a portal APIs allows for applications to dynamically request
> > access to privileged functionality, for example access to arbitrary
> > file system locations, cameras, geo location, or screen casting.
> That's quite a long sentence. Let me dissect it a bit. What kind of
> API are we talking about? The xdg-portal-desktop one? Who defines the
> "build time configured list of API"? Are we talking about the "build"
> of the Flatpak? Is it the Manifest's "finish-args" as described this
> way in the Flatpak documentation? [1]

sort-of, there's a confusion of terms. "API" stands primarily for a DBus API
but you'll probably think of X11 and Wayland as sockets. for the purpose
here you can consider them as APIs as well.

When you build a flatpak application, you specify what that application can
access outside the sandbox, that's your [1] link. by default, a sandboxed
application does not have X11 or Wayland access.

you can allow access to those or any API at build time, e.g.
--talk-name=org.freedesktop.EI would allow the application to talk to a EIS
server directly without the portal in between. These permissions are
compiled in and listed by the flatpak itself - they're not dynamic like the

Problem with any build-time permissions is the portal has no control over
it. This particularly shows the issue with sockets which are a complete
side-channel. A DBus API will be called every time
it's needed - that allows for a gatekeeper in between. A socket, once
established, is largely outside the control of such a gatekeeper. XTEST for
example floats along on the rest of X, you cannot allow an application to
use X for display but disallow XTEST in a portal, support for this would
have to be implemented in X itself. The same would be true for a Wayland
virtual input protocol.

EI is (will be) a combination of API + socket, similar to screencasting -
negotiation is handled by the portal but once the connection is established
the data is outside the portal's control. We could make the communication
fully dbus-y so we can filter at any point but I don't think that would
provide a lot of benefit.

The socket approach here is acceptable because it's very *specific* for what
it does. It only does emulated input, so giving permission to that implies
you want that to happen. Giving permission for X (or Wayland) does not by
default mean you want emulated input to happen through those protocols.

> > 2) It provides, using backends, methods for implementing user
> > interactive permission management. For arbitrary file system access,
> > this may involve e.g. opening a file using a file selection dialog, or
> > for screen casting this may mean actively choosing what part of your
> > screen should be shared.
> Right, what the basic idea of the portals is, is pretty clear to me.
> Basically it pipes requests of sandboxed apps through an
> authentication and permission system in case they want to interact
> with outside their sandbox. It's more about the cases where they
> don't. A Wayland client in a sandbox interacts via Wayland protocol
> with the outside of their sandbox, but that's not going through
> xdg-portals, or is there a permission to block it from that?

For flatpak at least, you need to explicity allow wayland access
(--socket=wayland) at which point it's basically a wayland-sized hole in the

> > 3) It manages remembered access, using a common permission store[0]. For
> > example if an application was permanently denied camera access, the
> > portal will know about this and not query the portal backend.
> Yea, I quickly did an online search for a GUI to it and found [2]
> which looks awesome. Also answers my question above: there exist
> permissions to block a sandboxed app from Wayland or X11. But I assume
> a user won't be asked for every new GUI app he installs if it is
> allowed to show some pixels and instead the permission is by default
> set to allowed. Looking back at it the GUI app should set this as a
> permission in their Manifest file, which is like a default on install.

It does indeed ask, or at least tell you:

$ flatpak install --user org.gimp.GIMP
Looking for matches…
Found similar ref(s) for ‘org.gimp.GIMP’ in remote ‘flathub’ (user).
Use this remote? [Y/n]: y

org.gimp.GIMP permissions:
    ipc      network      x11      file access [1]      dbus access [2]      tags [3]

    [1] /tmp, host, xdg-config/GIMP, xdg-config/gtk-3.0, xdg-run/gvfs
    [2] org.freedesktop.FileManager1, org.gtk.vfs, org.gtk.vfs.*
    [3] stable


Proceed with these changes to the user installation? [Y/n]: 

So the built-in permissions for gimp include x11 and direct access to the
org.freedesktop.FileManager1 DBus API. To re-iterate my above point -
because gimp has x11 access, the sandbox cannot stop it from emulating input
via XTEST. Likewise, if wayland was parts of the permission you cannot
arbitrate access to wayland protocols through a portal.

For the rest I'm going let Jonas answer since there are some questions in
there where I'm not sure my answer would be correct :)


> > In the diagram you can see 5 "interactions" between different components
> > that takes place, (1), (2), (3), (4) and (5), resulting in the side
> > channel (C).
> >
> > (1) is the application making a request to be able to inject input
> > events.
> >
> > (2) is the portal, having authenticated the application the request came
> > from and verified the metadata, does a method call on behalf of the
> > application to the portal backend implementation to check with the user
> > then maybe open an Ei session.
> >
> > (3) is the portal backend, possibly having queried the user about
> > permissions, opening a new Ei session.
> >
> > (4) is the backend returning from the method call done in (2), possibly
> > with an open file descriptor to a Eis session.
> The portal backend creates the open file descriptor, something the
> sandboxed app can't do per se. In general a sandboxed app can not
> create arbitrary sockets, correct?
> > (5) the portal responds to the requests made from the application in
> > step (1). This response is then used to establish (C). See below.
> >
> > (C) is the newly established Eis channel where the application can
> > inject input using libei, and the compositor being able to process
> > injected input in a similar way to how it processes libinput events.
> >
> > (p) and (p') corresponds to permission store interaction (where p' is
> > optional but recommended). Either up front by the portal, or e.g. a
> > compositor may be permission store aware, so that it can terminate a
> > session that changes permission after access was originally granted.
> > This is for example how PipeWire handles camera access being revoked.
> What do you mean by "terminate a session that changes permission"? Who
> changed the permission in the first place? The user? For example in
> the Flatseal UI by switching one app off again?
> > Today, unsandboxed applications are treated on a per case basis. In some
> > cases (e.g. screen casts, screenshots), the only effect is that the name
> > of the application is not presented as part of a dialog, while in other
> > cases it simply defaults to some policy e.g. deny or grant.
> Do you mean non-sandboxed applications that still try to communicate
> with xdg-desktop-portal? They could also just talk directly to your
> Mutter dbus interface or does it only allow connections from
> xdg-desktop-portal's dbus "address"? If yes, this dbus
> address/name/identifier is not fakable?
> > The permission store itself doesn't require entries to have a sandboxed
> > application ID, but the portal itself currently doesn't have a way to
> > identify an application that isn't running inside a sandbox. Thus, if a
> > Ei session policy default is to ask, for a portal to be able to remember
> > the permission for an unsandboxed application, we would have to add a
> > way for the portal to blindly trust some ID or key of some sort the
> > application provides.
> What about the portal in this case being able to get additional
> information from other "trusted actors" like the Wayland server? In
> case of Xwayland the compositor could hand over a secret key at the
> start that Xwayland then can provide for queries to xdg-desktop-portal
> and then check back for every request with the compositor if the app
> that states to be "Xwayland" provided indeed this key.
> >
> > Xwayland would be considered an unsandboxed application, even if the
> > application a XTEST request came from was sandboxed. Exactly how to deal
> > with this, is an open question, e.g. whether to treat all "X11"
> > applications as one giant blob, or whether to distinguish between them,
> > depends on in what ways we would be able to let the portal trust
> > metadata coming from unsandboxed applications.
> >
> From my understanding there are basically three important client classes:
> * Unsandboxed app
> * Sandboxed Wayland app
> * Sandboxed X11 app
> Some random unsandboxed app can do whatever it wants but some system
> interfaces might be only accessible by xdg-portals like certain dbus
> addresses for example screencasting in Mutter (if that's not true tell
> me) and reading Peter's first email also libei is supposed to behave
> this way in a Gnome session. The question is in this case if such apps
> should be able to gain access to the system interfaces that are
> accessible only by xdg-portals through its permission system.
> Sandboxed Wayland apps are properly secure as long as there are no
> holes created by not secure Wayland protocol extensions.
> Sandboxed X11 apps are as secure as unsandboxed Xwayland is contained
> from the outside system since the X11 protocol design is per se not
> secure. So if Xwayland is not contained properly and has access to
> certain critical/global interfaces this could then be used as an
> attack vector from inside the sandbox to the outside. As an example a
> rogue sandboxed Xwayland app could fake input if Xwayland was allowed
> in general access to libei (that also holds for unsandboxed X11 apps,
> but for sandboxed ones it's more grave). On the other side if the
> access is asked for by Xwayland on a per-Xwayland-client-basis with
> Xwayland checking window name, PID (?) or something similar a rogue
> client could still try to gain access by posing as a different client
> that was already allowed for example by changing its window title and
> maybe PID (would this at all be doable for a sandboxed app?).
> With Xwayland having access to libei in some way I think at least for
> sandboxed X11 apps there must be no possibility for tampering.
> Unsandboxed X11 clients are not so important in comparison. If a
> non-sandboxed X11 client gains access to input emulation through
> Xwayland then so be it. Do you agree with this sentiment?
> [1] https://docs.flatpak.org/en/latest/sandbox-permissions.html#sandbox-permissions
> [2] https://www.omgubuntu.co.uk/2020/02/flatseal-manage-flatpak-permissions
> >
> > Jonas
> >
> >
> > [0] https://github.com/flatpak/xdg-desktop-portal/wiki/The-Permission-Store
> > >
> > > [1] https://gitlab.com/romangg/kwinft/-/commits/libei
> > > [2] https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/431
> > > [3] https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/465
> > >
> > > > The aim is that a client can simply iterate through all of the options until
> > > > finds a connection. Once that's found, the actual code for emulating input is
> > > > always the same so it's trivial to implement a client that works on any
> > > > compositor that supports some backend of libeis.
> > > > The server part only needs to care about the negotiation mechanisms it
> > > > allows, i.e. GNOME will only have dbus/portal, sway will only have... dunno,
> > > > fd exchange maybe?
> > > >
> > > > Next: because we have a separate channel for emulated input we can hook up
> > > > XTEST to use libei to talk to a compositor. I have a PoC implementation for
> > > > weston and Xwayland:
> > > >   https://gitlab.freedesktop.org/whot/weston/-/commits/wip/eis
> > > >   https://gitlab.freedesktop.org/whot/xserver/-/commits/wip/xwayland-eis
> > > > With that xdotool can move the pointer. Note this is truly the most minimal
> > > > code just to illustrate the point but you can fill in the blanks and do
> > > > things like the compositor preventing XTEST or not, etc.
> > > >
> > > > This is all in very early stages with very little error checking so things
> > > > will probably crash or disconnect unexpectedly. I've tried to document the
> > > > API to make the intentions clear but there are still some very handwavy
> > > > bits.
> > > >
> > > > Do let me know if you have any questions or suggestions please though.
> > > >
> > > > Cheers,
> > > >   Peter
> > > > _______________________________________________
> > > > wayland-devel mailing list
> > > > wayland-devel at lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/wayland-devel
> > > _______________________________________________
> > > wayland-devel mailing list
> > > wayland-devel at lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/wayland-devel

More information about the wayland-devel mailing list