Wayland Compositor Security Architecture and Privileged Client Management

A deep architectural analysis of display server security: the input/output CIA triad, screencasting, input emulation (libei/EIS), session locking (ext-session-lock-v1), and sandbox isolation (security-context-v1) under 2026 standards.

20 min read
ibrahimsql
3,868 words

Wayland Compositor Security Architecture and Privileged Client Management#

In an operating system, the display server is the ultimate architectural choke point. Every pixel rendered on the physical display must pass through the display server to reach the GPU rasterizer; conversely, every keystroke typed on the keyboard or coordinate clicked with a mouse must be received, decoded, and dispatched by the display server to the target client.

Under the legacy X11 architecture, this choke point operated under an ambient authority security model: any connected client could snoop the global event stream, enumerate and capture pixels from arbitrary windows, and inject synthetic keystrokes into other applications. This design left desktop environments structurally defenseless against background keyloggers, screen snooping, and local privilege escalation.

Wayland abolished this ambient authority model. In the core Wayland protocol, isolation is absolute by default: clients can only allocate their own private buffers (shm or DMA-BUF) and receive input events explicitly targeted at their focused surface (wl_surface).

However, for a modern desktop to function, certain specialized programs must inevitably break this strict isolation:

  • Screen recorders and video-conferencing suites must capture displays or windows.
  • Screen lockers must blank all outputs and intercept all global input.
  • Accessibility tools and remote desktop servers must emulate keyboard and mouse events.
  • Shell bars, docks, and notification daemons must position overlays and track foreign window states.

These applications are privileged clients. How the compositor defines, authorizes, enforces, and revokes these capabilities determines whether the modern Linux desktop can uphold its security boundaries.

This document provides a deep architectural analysis of the Wayland compositor security model, the input/output CIA triad, ext-session-lock-v1, libei/libeis, wp_security_context_manager_v1, and PipeWire/portal integrations as established in 2026.


1. The Display Server Security Triad (CIA Matrix)#

A display server mediates two unidirectional data streams between the human user and client processes:

  1. Input Stream: Physical data flowing from the user into the machine (keystrokes, mouse moves, touch gestures).
  2. Output Stream: Rendered data flowing from the machine to the user (window pixels, frame buffers, audio cues).
USER ^ | Output Stream (Rendered) | | Input Stream (Typed / Clicked) | v +-------------------------+ | DISPLAY SERVER | | (Wayland Compositor) | +-------------------------+ | ^ Buffer Commits (DMA-BUF) | | Event Delivery (wl_keyboard) v | CLIENTS (APPS)

For each stream, three canonical security properties apply: Confidentiality, Integrity, and Availability.

Detailed CIA Security Matrix#

Security DimensionInput Stream (Physical Keystrokes & Pointer Moves)Output Stream (Screen Pixels & Surfaces)
ConfidentialityKeystrokes are delivered exclusively to the focused client. Background processes cannot snoop the input stream (anti-keylogging).A client can only read its own pixel buffers. No client can capture pixels belonging to another application or the root screen (anti-screen capture).
IntegrityClients cannot forge synthetic keyboard or mouse events to simulate user interaction into other applications (anti-input injection / anti-spoofing).No client can alter or draw over another window's content, mimic server-side decorations, or deploy transparent clickjacking overlays.
AvailabilityNo rogue client can swallow all input or hold a permanent global keyboard/pointer grab, starving other applications of input.No client can permanently occlude the display, prevent other windows from mapping, or exhaust compositor GPU resources to freeze the session.

Architectural Comparison: Legacy X11 vs. Modern Wayland#

+---------------------+-----------------------------------+-----------------------------------+ | Property | Legacy X11 Posture | Modern Wayland Posture | +---------------------+-----------------------------------+-----------------------------------+ | Input | BROKEN (XSelectInput / XRecord | ENFORCED (Protocol lacks global | | Confidentiality | allows arbitrary eavesdropping) | listeners; targeted unicast only) | +---------------------+-----------------------------------+-----------------------------------+ | Output | BROKEN (XGetImage copies pixels | ENFORCED (Buffers isolated in GPU | | Confidentiality | from any window or root display) | memory via scoped DRM DMA-BUF) | +---------------------+-----------------------------------+-----------------------------------+ | Input Integrity | BROKEN (XTestFakeKeyEvent injects | ENFORCED (Synthetic input banned; | | | synthetic keystrokes into root) | libei/EIS portal broker required) | +---------------------+-----------------------------------+-----------------------------------+ | Output Integrity | PARTIAL (Window hierarchy can be | ENFORCED (Compositor has absolute | | | reparented and occluded at will) | authority over scene graph state) | +---------------------+-----------------------------------+-----------------------------------+ | Availability | WEAK (Global grabs allow denial- | STRONG (Compositor enforces focus | | | of-service and desktop lockups) | timeouts and surface lifecycle) | +---------------------+-----------------------------------+-----------------------------------+

2. End-to-End System & Compositor Security Architecture#

In a modern Linux desktop, the Wayland compositor serves as the single trusted arbiter between kernel hardware interfaces and unprivileged application runtimes:

+-----------------------------------------------------------------------------+ | PHYSICAL HARDWARE | | [Keyboard / Mouse] [Graphics Card / GPU] | +-------------------+-----------------------------------------+---------------+ | | | Raw evdev events | DRM/KMS v v +-----------------------------------------------------------------------------+ | LINUX KERNEL | | /dev/input/event* /dev/dri/card* | +-------------------+-----------------------------------------+---------------+ | | | libinput event processing | GBM / DMA-BUF v v +-----------------------------------------------------------------------------+ | WAYLAND COMPOSITOR | | (GNOME Mutter / KDE KWin / wlroots) | | | | +-----------------------------------------------------------------------+ | | | SECURITY & PRIVILEGE ENGINE | | | | | | | | +--------------------------------+ +-----------------------------+ | | | | | wp_security_context_manager | | ext_session_lock_manager | | | | | | (Sandbox Client Scoping) | | (Atomic Screen Locker) | | | | | +--------------------------------+ +-----------------------------+ | | | | +--------------------------------+ +-----------------------------+ | | | | | libeis | | wlr-screencopy | | | | | | (Emulated Input Server) | | (Scoped Frame Captures)| | | | | +--------------------------------+ +-----------------------------+ | | | +-----------------------------------------------------------------------+ | | | | +-------------------------------------|---------------------------------------+ | D-Bus / PipeWire v +-----------------------------------------------------------------------------+ | PORTAL & MEDIA LAYER | | | | +----------------------------+ +--------------------------+ | | | xdg-desktop-portal | | PipeWire | | | | (User Consent Broker) | | (Zero-Copy DMA-BUF) | | | +--------------+-------------+ +------------+-------------+ | +--------------------|------------------------------------|-------------------+ | | v v +-----------------------------------------------------------------------------+ | CLIENT LAYER | | | | +---------------------------+ +----------------------------------------+ | | | Sandboxed Application | | Privileged Session Tool | | | | (Web Browser, Flatpak) | | (OBS Studio / Screen Locker / VNC) | | | | - Scoped Wayland socket | | - Portal-approved PipeWire node | | | | - Own surfaces only | | - libei-authenticated input socket | | | +---------------------------+ +----------------------------------------+ | +-----------------------------------------------------------------------------+

3. Privileged Operations & Modern 2026 Protocols#

1. Screen Capture & Streaming (ScreenCast)#

  • The Vulnerability: Under X11, calling XGetImage allowed any unprivileged process to quietly dump the framebuffer of password managers, private chat sessions, or full workspaces.
  • Modern Portal & Protocol Workflow:
    1. The client connects to org.freedesktop.portal.ScreenCast via the D-Bus session bus and invokes CreateSession.
    2. The portal frontend prompts the user with a trusted system modal dialog: "Which monitor or window do you want to share?"
    3. Upon user approval, the compositor instantiates a PipeWire node bound specifically to the chosen surface's GPU buffer.
    4. The portal returns a PipeWire file descriptor (FD) to the client. The client ingests frames via zero-copy DRM DMA-BUF GPU buffer transfers. The client never accesses unshared monitors or surfaces.

2. Emulated Input & Remote Desktop (libei & libeis)#

  • The Vulnerability: The legacy XTest extension permitted arbitrary keycode injection, enabling attackers to type terminal commands into background windows.
  • The libei Architecture: The Emulated Input System (EIS), standardized across desktop environments:
    • libei: Client-side library used by input-injecting applications (e.g., Synergy/InputLeap, TeamViewer, test automation).
    • libeis: Server-side library embedded directly inside the Wayland compositor.
    • Protocol Flow: The client invokes org.freedesktop.portal.RemoteDesktop over D-Bus. After explicit user authorization, the portal calls ConnectToEIS() on the compositor, receiving a dedicated UNIX socket pair.
    • The client receives the socket FD (ei_setup_backend_fd) and negotiates a virtual keyboard or pointer device. The compositor tags all incoming events as synthetic, keeping them strictly segregated from physical libinput events and suppressing them when security-critical surfaces (lock screens, password prompts) are active.
+-----------------------+ | Remote Desktop App | | (InputLeap / AnyDesk)| +-----------+-----------+ | 1. D-Bus: org.freedesktop.portal.RemoteDesktop.SelectDevices() v +-----------------------+ | xdg-desktop-portal | <--- Solicits explicit user consent via desktop modal +-----------+-----------+ | 2. Authorized: Calls ConnectToEIS() on compositor v +-----------------------+ | Wayland Compositor | <--- Generates libeis socket pair; | (libeis) | returns client FD to portal broker +-----------+-----------+ | 3. Portal returns FD to client (ei_setup_backend_fd) v +-----------------------+ | Remote Desktop App | <--- Dispatches synthetic input events | (libei) | over isolated EIS protocol channel +-----------------------+

Deep Source Code Analysis: libei C Client Implementation#

Unlike uncontained XTestFakeKeyEvent() invocations in legacy X11, libei enforces transaction frame semantics (ei_device_frame) and cryptographically or portal-negotiated session authorization:

/* libei C Client - Safe Emulated Input Dispatch */ #include <libei-1.0/libei.h> #include <linux/input-event-codes.h> #include <stdio.h> void send_emulated_keystroke (int eis_socket_fd) { /* 1. Initialize client context over portal-brokered EIS socket */ struct ei *ei = ei_new_sender (NULL); if (ei_setup_backend_fd (ei, eis_socket_fd) < 0) return; /* 2. Configure virtual seat and declare keyboard capability */ struct ei_seat *seat = ei_get_default_seat (ei); struct ei_device *kbd = ei_device_new (seat); ei_device_configure_capability (kbd, EI_DEVICE_CAP_KEYBOARD); /* 3. Begin emulated event transaction */ ei_device_start_emulating (kbd, 1); uint64_t timestamp = ei_now (ei); /* Emit key press event (KEY_ENTER down) */ ei_device_keyboard_key (kbd, KEY_ENTER, 1); /* Commit frame boundary to signal complete hardware packet */ ei_device_frame (kbd, timestamp); /* Emit key release event (KEY_ENTER up) */ ei_device_keyboard_key (kbd, KEY_ENTER, 0); ei_device_frame (kbd, timestamp + 25000); // 25ms delay /* 4. Conclude emulation transaction and teardown memory */ ei_device_stop_emulating (kbd); ei_device_unref (kbd); ei_unref (ei); }

On the compositor side (libeis), incoming events are never intermingled directly with physical libinput streams; they carry an immutable is_emulated = true attribute and are automatically dropped when high-security surfaces (password prompts, session lock screens) hold focus.


3. Session Locking Protocol (ext-session-lock-v1)#

  • The Vulnerability: Historical screen lockers (e.g., XScreenSaver, i3lock, early Wayland hacks) functioned by creating a topmost fullscreen window and grabbing input. If the locker encountered a segmentation fault (SIGSEGV) or was terminated via an unprivileged signal, the lock window disappeared, immediately exposing the running desktop and all active windows.
  • Protocol Guarantees (ext-session-lock-v1):
    • The locking client acquires the ext_session_lock_manager_v1 global and requests a lock.
    • The compositor suspends all desktop rendering and assigns an ext_session_lock_surface_v1 per physical monitor.
    • Crash Resilience: If the lock client crashes or disconnects while the session is locked, the compositor never reveals the desktop. Instead, the compositor immediately blanks all displays with an opaque solid color and freezes all input routing. The session cannot be unlocked until a valid locker re-authenticates or the user resets via a virtual console.

Deep Source Code Analysis: ext-session-lock-v1.xml & wlroots Crash Resilience#

The protocol XML state machine (staging/ext-session-lock/ext-session-lock-v1.xml) enforces strict separation between session enable and teardown:

<interface name="ext_session_lock_v1" version="1"> <description summary="active session lock object"> A client uses this object to hold the session lock. Only when authentication succeeds may 'unlock_and_destroy' be invoked. Standard 'destroy' signifies that the lock client exited prematurely. </description> <request name="destroy" type="destructor"/> <request name="get_lock_surface"> <arg name="id" type="new_id" interface="ext_session_lock_surface_v1"/> <arg name="surface" type="object" interface="wl_surface"/> <arg name="output" type="object" interface="wl_output"/> </request> <request name="unlock_and_destroy" type="destructor"/> <event name="locked"/> <event name="finished"/> </interface>

In the wlroots implementation (wlr/types/wlr_session_lock_v1.c), handling a client termination without prior enable prevents desktop exposure:

/* wlroots wlr_session_lock_v1.c - Crash Resilience Enforcement */ static void session_lock_resource_destroy (struct wl_resource *resource) { struct wlr_session_lock_v1 *lock = wlr_session_lock_v1_from_resource (resource); /* If the lock client disconnected without calling unlock_and_destroy */ if (!lock->unlocked) { /* CRITICAL SECURITY GUARANTEE: Under no circumstances are desktop surfaces revealed! */ wlr_log (WLR_ERROR, "Session locker client crashed or disconnected; session remains locked!"); /* Invalidate current lock object while retaining locked state */ lock->manager->current_lock = NULL; /* Lock compositor output to opaque solid black fallback and drop all input focus */ compositor_enforce_blank_screen_fallback (lock->manager); return; } /* Only on valid unlock_and_destroy are normal desktop surfaces restored */ compositor_unfreeze_normal_desktop (lock->manager); }

This mechanism eliminates the classic X11 physical bypass where sending kill -9 or triggering a crash in a locker software exposed the full desktop workspace.


4. Sandbox Client Scoping (wp_security_context_manager_v1)#

  • Mechanism: Sandboxing runtimes (Flatpak, Bubblewrap) call create_listener on the compositor's security context manager before spawning the child process.
  • Enforcement: Connections arriving on the registered socket inherit metadata (app_id, sandbox_engine).
  • Scoping: The compositor dynamically filters the global registry (wl_registry.global), hiding sensitive protocols like wlr-screencopy, ext-session-lock-v1, and zwlr_layer_shell_v1 from sandboxed clients.
  • No Nesting: Any attempt by a sandboxed client to register a subordinate security context results in an immediate protocol error and termination.

Source analysis: the security-context-v1.xml contract#

The state machine in staging/security-context/security-context-v1.xml has three ordered steps:

<interface name="wp_security_context_manager_v1" version="1"> <request name="create_listener"> <arg name="id" type="new_id" interface="wp_security_context_v1"/> <arg name="listen_fd" type="fd" summary="listening socket FD"/> <arg name="close_fd" type="fd" summary="FD signaling when done"/> </request> </interface> <interface name="wp_security_context_v1" version="1"> <request name="set_sandbox_engine"> <arg name="name" type="string" summary="the sandbox engine name"/> </request> <request name="set_app_id"> <arg name="app_id" type="string" summary="the application ID"/> </request> <request name="set_instance_id"> <arg name="instance_id" type="string" summary="the instance ID"/> </request> <request name="commit" summary="register the security context"/> </interface>

Rules: set_sandbox_engine uses reverse-DNS (org.flatpak; well-known engines are listed in engines.md). app_id plus engine identifies the application; instance_id plus engine identifies the running instance. commit is atomic; any request other than destroy afterwards is a protocol error (already_used). Setting the same field twice is already_set; inconsistent metadata yields invalid_metadata. The manager is not exposed to already-sandboxed connections, or nested is sent — nesting is forbidden because it could escalate a sandboxed client. The compositor never advertises privileged globals to a security-context connection, so even an LD_PRELOAD hook cannot use a protocol it never sees.


4. Threat Model & Attack Surface Analysis#

+-----------------------------------------------------------------------------+ | ATTACK SURFACE VECTORS | | | | [Vector A: Unprivileged Host Malware] | | - Runs as current user without root privileges. | | - Objectives: Background keylogging, persistent screen recording. | | - Wayland Defense: No global event listeners; screen access isolated | | behind portal approvals and DRM DMA-BUF allocations. | | | | [Vector B: Malicious Sandboxed Container / Web App] | | - Confined within container or Flatpak sandbox. | | - Objectives: Escape sandbox via Wayland socket communication. | | - Wayland Defense: wp_security_context_manager prevents binding of | | privileged globals. | | | | [Vector C: Xwayland Legacy Side-Channel Attacks] | | - Targets X11 applications running through the compatibility bridge. | | - Wayland Defense: Xwayland clients cannot observe native Wayland surfaces.| | Modern compositors isolate Xwayland instances per client or disable | | Xwayland by default. | +-----------------------------------------------------------------------------+

The Xwayland Security Conundrum#

The transition from X11 to Wayland required supporting legacy software through Xwayland, an X11 server running as a Wayland client.

This architecture introduces an important security consideration:

  1. All legacy X11 applications connected to the same Xwayland instance can snoop each other's keystrokes and capture each other's windows.
  2. However, Xwayland clients have zero visibility into native Wayland applications. A legacy terminal running in Xwayland cannot intercept keystrokes entered into a native Wayland password prompt or web browser.
  3. In modern hardened workstations, compositors support isolated, per-application rootless Xwayland instances or restrict Xwayland activation strictly on demand.

5. Practical Security Auditing & Diagnostics Lab#

Security practitioners can audit compositor capabilities, active globals, and security contexts using standard command-line tools:

1. Enumerating Compositor Global Interfaces#

# Query the Wayland compositor for registered global objects wayland-info
  • Verification: Inspect the output for wp_security_context_manager_v1, ext_session_lock_manager_v1, and screencopy protocols.
# Filter for security-critical protocols wayland-info | grep -E 'security_context|session_lock|screencopy|input_capture'
  • Expected Posture: An enterprise-ready workstation must expose ext_session_lock_manager_v1. If zwlr_screencopy_manager_v1 is exposed unconditionally to unprivileged clients, background screen recording without portal prompts is possible.

2. Auditing Active PipeWire Screen Sharing Nodes#

# Inspect PipeWire nodes for active media streaming endpoints pw-cli list-objects Node | grep -E 'node.name|media.class'
  • Forensic Indicator: An active screen-sharing session will instantiate a node with media.class = "Video/Source". The presence of such a node when no recording or video call is active indicates an unauthorized background capture stream.

3. Verifying Session Lock Integrity#

# Verify kernel session lock state loginctl show-session "$XDG_SESSION_ID" -p LockedHint
  • Analysis: When the screen is locked, LockedHint must report yes. If the screen appears visually locked but LockedHint=no, the lock implementation is relying on legacy window grabs rather than modern session lock protocols.

4. Auditing Raw Input Device Nodes#

# Verify permissions on kernel evdev and uinput device nodes ls -l /dev/uinput /dev/input/event*
  • Expected Permissions: All input nodes must be restricted to root and group input (crw-rw----). If any device node is world-readable or world-writable, any local process can read raw scan codes or inject hardware-level keystrokes, completely bypassing Wayland's security guarantees.

6. Design Rules for Desktop Compositors#

Developers building Wayland compositors, desktop shells, or privileged utilities must adhere to core architectural principles:

  1. Deny Protocol Binding by Default: Privileged globals (ext-session-lock-v1, layer-shell, screencopy) must never be advertised indiscriminately to all clients. Compositors should restrict these globals based on process metadata, or require client connections established via authenticated channels.

  2. Enforce Clean Failure Modes: When an unauthorized client attempts to bind a privileged global, the compositor must reject the binding cleanly or send a fatal protocol error (wl_error), terminating the rogue connection immediately.

  3. Provide Runtime Revocation Controls: Screen sharing and remote input streams must not be open-ended. Compositors and portals must maintain visible indicators (e.g., status tray icons, screen edge tints) and provide immediate user controls to terminate active sessions.

  4. Never Rely on Client-Asserted Identifiers: Compositors must never trust process names, window titles, or binary paths supplied over Wayland or D-Bus messages. Client identity must be established exclusively via kernel credentials (SO_PEERCRED), cgroup paths, and verified sandbox metadata.


7. Summary: The 2026 Display Security Standard#

The primary achievement of the Wayland architecture is not graphical performance, but the establishment of a verifiable security model:

  • The ambient authority flaws of X11 have been replaced with an explicit, capability-based display server architecture.
  • By combining xdg-desktop-portal, PipeWire zero-copy DMA-BUF streaming, libei/libeis input emulation, ext-session-lock-v1 session locking, and wp_security_context_manager_v1 sandbox tagging, the 2026 Linux desktop provides end-to-end confidentiality, integrity, and availability guarantees.
  • Privileged operations no longer require compromising the entire desktop session; every capability is individually scoped, explicitly authorized, and strictly policed by the compositor.

Input Method Visibility: the input-method-v1 surface#

The protocol stack has a layer that sits between the seat and the text field: input methods. Frameworks such as IBus and Fcitx expose a Wayland client protocol (input-method-v1) so a compositor can hand keystrokes to an input method engine for composition and suggestion. To compose, the engine receives the raw key events for a text field — in effect, a privileged listener inside the desktop.

That means an input method client is a real keylogging surface. A compromised or malicious IM extension can reconstruct what the user types before the application ever sees it, and it does this over a legitimate Wayland protocol with no kernel privilege required. Defenses are composition: keep desktops on the fewest IM backends possible, only install the backends you use, run them in a sandbox where the platform supports it (Flatpak GNOME runtime ships IBus in a Flatpak sandbox on most setups), and on systems that never need non-Latin input, disable or remove the IM to kill the surface.

A related, lower-visibility protocol is text-input-v1/text-input-v3, which a text field uses to tell the IM what to replace. It is less powerful than input-method-v1 — it does not hand over raw events — but it still carries buffer contents into the IM process. Audit it with the same rule: fewer IM clients, fewer routes to keystrokes.

On X11 there is no equivalent boundary at this level; IBus/Fcitx there read raw X input directly, which is part of why the X11 input model is considered broader. Wayland's seat split — keyboard events go through the compositor, and only the input-method-v1 client participating in a session sees them — is a genuine narrowing, and it is worth stating that explicitly rather than assuming Wayland magically removed the problem.

Session-Level Reality: RemoteDesktop v2, EIS, and Persistence#

The grant you as a user see as "Allow remote input" is a session, not a toggle. The interface documentation for org.freedesktop.portal.RemoteDesktop (version 2) lays the lifecycle out plainly:

  1. CreateSession opens a session object owned by the caller.
  2. SelectDevices declares which device classes are wanted — keyboard, pointer, touchscreen — and returns which the desktop granted.
  3. Start presents the consent dialog; on success the session is live.

Only from then can input be injected. Two injection paths exist, and the distinction matters for what an analyst sees:

  • EIS (recommended): ConnectToEIS hands the caller a file descriptor backed by a libei sender context, and events flow over the EI protocol through that fd. Once this path is connected, the D-Bus Notify* methods must not be used; the session is essentially handed a dedicated pipe.
  • D-Bus Notify* methods: NotifyPointerMotion, NotifyPointerMotionAbsolute, NotifyKeyboardKeycode, NotifyTouch* etc. send each event as a D-Bus call. It works without libei linked, but every event is a D-Bus transaction, which makes it chatty and easier to spot on a system bus monitor.

Persistence changed in v2. The application can ask for persist_mode and receive a restore_token, so the user does not have to re-approve on every launch. Sessions created here are the semantic owner: when a remote-desktop session is combined with screen capture, persistence is managed through org.freedesktop.portal.RemoteDesktop, and the matching options on ScreenCast.SelectSources must not be used. A clipboard pull-in is a separate grant via Clipboard.RequestClipboard inside the same session scope.

From a detection standpoint the useful invariant is: anything injecting synthetic input over this portal either holds a live RemoteDesktop session handle (EIS fd or D-Bus method stream), or it is not going through the portal at all (that is the evdev/uinput path, a different boundary entirely — see the keylogging series). A session handle appears in the portal's session table on the bus (org.freedesktop.portal.Desktop/SessionX style objects), which is the cheapest lookup defenders get from the running system.

Source correspondence: what the protocol guarantees#

The isolation claims in this document verify against Wayland's own code (in a wayland-src clone):

  • protocol/wayland.xml: wl_seat version 11 is a keyboard+pointer+touch group; get_keyboard returns that seat's wl_keyboard. The wl_keyboard logical state is active surface, down keys, modifiers, and group. enter sets the active surface (never sent if one already exists), leave resets it, and key (serial, time, key, state) is only sent with an immediately-prior active surface. key is a raw platform code that gains meaning with the xkb_v1 keymap (+8). repeat_info is v4, release is v3, the repeated state is v10.
  • src/wayland-client.c:66: struct wl_proxy holds display, queue, refcount, user_data, dispatcher, version. The :659 wl_proxy_add_listener rule: return -1 if a listener or dispatcher exists, abort on wrappers. A privileged-listener spoof therefore dies on the second install.
  • Practical result: catching wl_keyboard_interface via LD_PRELOAD (Aishou/wayland-keylogger, Keylogger.cpp:129-162) only ever sees the infected process's own proxy; a neighbor client's enter/key flow never reaches that process. See the keylogging series for the full PoC teardown.
---
Share this post:

What do you think?

React to show your appreciation

Related Posts