Skip to content

O_RDONLY|O_NOFOLLOW on /proc/<pid>/root always returns ELOOP — unsandboxed process registration silently fails, breaking KDE screen sharing #1953

@OrcVole

Description

@OrcVole

Operating System

Bazzite 43.20260406 (Fedora 43 immutable / OSTree / composefs)

XDG Desktop Portal version

Other

XDG Desktop Portal version (Other)

1.20.3-2.fc43.x86_64

Desktop Environment

Other

Desktop Environment (Other)

KDE Plasma 6.6.3 (Wayland session)

Expected Behavior

The portal successfully registers unsandboxed processes (such as KWin) as host applications. KWin's screencast plugin creates the zkde_screencast_unstable_v1 Wayland global. Screen sharing and PipeWire screen capture work normally.

Current Behavior

Every registration attempt from an unsandboxed process fails with:

Could not register app ID: Unable to open /proc/<pid>/root
On KDE Plasma, this prevents KWin's screencast plugin from creating zkde_screencast_unstable_v1. Screen sharing silently fails for the entire session — no error is shown to the user.

The failure is caused by the portal opening /proc/<pid>/root with O_RDONLY | O_NOFOLLOW. That path is a kernel magic symlink; POSIX requires ELOOP when O_NOFOLLOW is used on any symlink with O_RDONLY. This is not a race, not SELinux, not seccomp — it is a flag combination that is unconditionally invalid for a symlink on any Linux system.

Confirmed via Python on the affected system:

os.open('/proc/<pid>/root', os.O_PATH | os.O_NOFOLLOW)
# → OK

os.open('/proc/<pid>/root', os.O_RDONLY | os.O_NOFOLLOW)
# → FAIL: [Errno 40] Too many levels of symbolic links

The string O_PATH fd was opened O_NOFOLLOW appears in the portal binary, confirming the code path. The error repeats on every portal restart across the entire session lifetime — it is not a startup timing issue.

Steps to Reproduce

  1. Log in to a KDE Plasma 6 Wayland session on any immutable Fedora derivative (Bazzite, Kinoite, Silverblue).
  2. Attempt to share your screen — via OBS PipeWire capture, browser WebRTC, or any application that calls org.freedesktop.portal.ScreenCast.CreateSession.
  3. Nothing happens. The chooser dialog never appears.

To confirm the failure directly:

# Check that the Wayland screencasting protocol is absent
wayland-info | grep zkde_screencast
# (returns nothing)

# Check KWin's journal for the registration error
journalctl --user -u plasma-kwin_wayland --boot --no-pager \
    | grep "Unable to open"
# Returns: "Could not register app ID: Unable to open /proc/<pid>/root"
# — repeated on every xdg-desktop-portal restart throughout the session

The failure occurs on every boot, every portal restart, with no variation in timing or system state.

Anything else we should know?

Proposed fix:

Replace the direct O_RDONLY | O_NOFOLLOW open with a two-step O_PATH + openat:

/* Step 1: get an O_PATH fd to the symlink target without following */
int path_fd = open(proc_path, O_PATH | O_NOFOLLOW | O_CLOEXEC);
if (path_fd < 0) { /* handle error */ }

/* Step 2: open the directory through the O_PATH fd */
int root_fd = openat(path_fd, ".", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
close(path_fd);

Both steps succeed on the affected system (confirmed via Python). O_PATH bypasses the symlink restriction; openat through the resulting fd resolves correctly.

Secondary issue: The portal also emits Realtime error: Could not get pidns for pid <N>: Could not fstatat ns/pid: Not a directory at session startup, causing it to crash and restart. This is a separate bug — the realtime monitor calls fstatat(ns/pid) on kernel threads and short-lived processes that do not expose a PID namespace. It compounds the above failure by creating a crash window at session start but is not the root cause.

Secondary KDE report: KWin's screencast plugin should create zkde_screencast_unstable_v1 regardless of whether portal registration succeeds — registration should be best-effort, not a hard prerequisite. Filed separately at bugs.kde.org.

System details:

  • Kernel: 6.17.7-ba29.fc43.x86_64
  • GPU: NVIDIA RTX 5090, driver 595.58.03 open modules
  • xdg-desktop-portal-kde: 6.6.3-1.fc43.x86_64
  • SELinux: Enforcing, all processes unconfined_t (confirmed not the cause)
  • Seccomp on portal service: disabled (confirmed not the cause)
  • ProtectProc on portal service: default (confirmed not the cause)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions