blog

git clone https://git.ce9e.org/blog.git

commit
d560e68d628f2c30c16904b8c391495bb8f308cc
parent
2fbf46a5745f4ad5deca7c7c4840d614fadfb1bd
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2025-10-11 15:19
add post on wayland security

Diffstat

A _content/posts/2025-10-03-wayland-security/index.md 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1 files changed, 122 insertions, 0 deletions


diff --git a/_content/posts/2025-10-03-wayland-security/index.md b/_content/posts/2025-10-03-wayland-security/index.md

@@ -0,0 +1,122 @@
   -1     1 ---
   -1     2 title: Privileged Wayland Clients
   -1     3 date: 2025-10-03
   -1     4 tags: [wayland, security]
   -1     5 description: "How do privileged clients in Wayland work exactly? Well, it's complicated."
   -1     6 ---
   -1     7 
   -1     8 When Wayland arrived on the scene some time around 2013, it promised increased
   -1     9 security: in X11, any client can monitor the inputs and outputs of other
   -1    10 clients. This allows to implement useful features such as screenshot tools and
   -1    11 virtual keyboards, but also malicious tools like screen scrapers and
   -1    12 keyloggers. So in the name of security, Wayland did away with all of that.
   -1    13 
   -1    14 This resulted in a bit of a [divide in the
   -1    15 community](https://blogs.kde.org/2020/10/11/linux-desktop-shell-ipc-wayland-vs-d-bus-and-lack-agreement-when-use-them/):
   -1    16 Some projects (like Gnome) chose to implement the missing features directly
   -1    17 in their compositor. Other projects (like wlroots) wanted to go with a more
   -1    18 modular approach where users could mix and match components. So they went ahead
   -1    19 and defined Wayland protocol extensions for the missing features.
   -1    20 
   -1    21 To avoid reintroducing all the security issues of X11, these protocol
   -1    22 extensions are intended to only be used by "privileged clients". How does that
   -1    23 work exactly?
   -1    24 
   -1    25 ## Identifying Clients
   -1    26 
   -1    27 Well, it's complicated.
   -1    28 
   -1    29 Say sway wants to delegate screenshots to
   -1    30 [flameshot](https://github.com/flameshot-org/flameshot/). It could use
   -1    31 `wl_client_get_credentials()` to get the PID of each client and then use
   -1    32 `wl_display_set_global_filter()` to block access to the relevant interfaces
   -1    33 unless `/proc/PID/exe` links to the flameshot binary.
   -1    34 
   -1    35 While this sounds good in theory, it has a couple of issues: `/proc/PID/exe`
   -1    36 can be faked using `LD_PRELOAD`, and accessing `/proc/` is vulnerable to race
   -1    37 conditions.
   -1    38 
   -1    39 Discussion quickly [shifted towards
   -1    40 sandboxing](https://gitlab.freedesktop.org/wayland/weston/-/issues/206#note_183479),
   -1    41 because processes that are not sandboxed can read all of the user's files,
   -1    42 which already is the worst case scenario, and can change the compositor's
   -1    43 configuration, which nullifies any restrictions defined there. It was decided
   -1    44 that any efforts to restrict access to privileged interfaces should focus on
   -1    45 sandboxed application. Unsandboxed applications would always be privileged.
   -1    46 
   -1    47 This lead to the
   -1    48 [security-context](https://wayland.app/protocols/security-context-v1) protocol
   -1    49 extension, which allows sandboxing engines like Flatpak to use a separate,
   -1    50 tagged socket for sandboxed applications.[^1] Most compositors simply block
   -1    51 access to all privileged interfaces for such clients.
   -1    52 
   -1    53 While this is progress, there are still a lot of unsandboxed applications, and
   -1    54 I do not see that changing any time soon. I think we can do better!
   -1    55 
   -1    56 [^1]: [way-secure](https://git.sr.ht/~whynothugo/way-secure) is another,
   -1    57 	standalone implementation.
   -1    58 
   -1    59 ## Meaningful Interaction
   -1    60 
   -1    61 Another option would be to ask the user for confirmation every time a
   -1    62 privileged interface is accessed. However, [Matthias Clasen argued in
   -1    63 2019](https://www.youtube.com/watch?v=bIzJyp8sb70) that a simple confirm dialog
   -1    64 would just [annoy
   -1    65 users](https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1970#note_1288230).
   -1    66 So instead he recommends to require *meaningful interaction*.
   -1    67 
   -1    68 For example, when you try to pick a color in Gimp, the meaningful interaction
   -1    69 would be to select a pixel on the screen. In technical terms, Gimp could talk
   -1    70 to xdg-desktop-portal, which talks to a portal backend, which in turn has
   -1    71 privileged access to the compositor. In exchange for the privileged access, the
   -1    72 portal backend guarantees to prevent abuse by requiring a user interaction.
   -1    73 
   -1    74 The compositor still needs a reliable way to identity the portal backend. So
   -1    75 user interaction is not a solution to the privileged client issue. Instead, it
   -1    76 is a prerequisite that privileged clients have to satisfy.
   -1    77 
   -1    78 ## Is there a better way?
   -1    79 
   -1    80 When I press the "print" key on my keyboard, my compositor spawns
   -1    81 a screenshot tool (in my case `grim`), which then connects back to the
   -1    82 compositor. So far, we have tried to decide whether that tool should get access
   -1    83 to privileged interfaces when it connects, either based on its identity or on
   -1    84 user interaction. But at that point, the meaningful interaction has already
   -1    85 happened. The meaningful interaction was pressing the "print" key.
   -1    86 
   -1    87 This really clicked for me when I realized that all privileged clients are
   -1    88 spawned by the compositor, either on user interaction or on startup (in which
   -1    89 case they require meaningful user interaction themselves). We just need to find
   -1    90 a way to pass additional privileges to the process when it is spawned, without
   -1    91 allowing other processes to steal them.
   -1    92 
   -1    93 I found the answer in a [great article by Martin Roukala from 2014
   -1    94 (!)](https://mupuf.org/blog/2014/02/19/wayland-compositors-why-and-how-to-handle/):
   -1    95 Usually, wayland clients use the `WAYLAND_DISPLAY` environment variable to find
   -1    96 the socket that they connect to. But there is also `WAYLAND_SOCKET`, which
   -1    97 tells them to use an already connected file descriptor instead. This way you
   -1    98 can pass an anonymous socket that cannot be accessed by any other process.
   -1    99 
   -1   100 Unfortunately, there is one major issues with this approach: The privileges
   -1   101 only apply to the first client, not any of its children. For example, `swayidle
   -1   102 timeout 600 swaylock` would not work because only `swayidle` would get the
   -1   103 privileged socket. `swaylock` would use the regular socket, without access to
   -1   104 the privileged `ext_session_lock_manager_v1` interface.
   -1   105 
   -1   106 Anyways, I implemented this approach for labwc in
   -1   107 [#3089](https://github.com/labwc/labwc/pull/3089). I have been using this
   -1   108 branch for a couple of days now, and it seems to work fine. I don't expect that
   -1   109 it will be merged though because it contains quite some breaking changes.
   -1   110 
   -1   111 ## Conclusion
   -1   112 
   -1   113 The status quo is that wlroots-based compositors implement privileged
   -1   114 interfaces, and any non-sandboxed processes can access them. That is way too
   -1   115 much attack surface for my taste.
   -1   116 
   -1   117 The big question for me is whether the `WAYLAND_SOCKET` approach I described
   -1   118 above is a step in the right direction or mere security theater. I have a hard
   -1   119 time deciding either way.
   -1   120 
   -1   121 Next I would like to look more into sandboxing to see if I can apply more
   -1   122 general restrictions, especially to terminal applications.