diff --git a/AGENTS.md b/AGENTS.md index 01fd8a4f8..f25f47536 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -266,9 +266,11 @@ Key files: - The probe and playback helper share one sanitized loader environment: ambient audit, preload, library, graphics-driver, and shell-startup overrides are removed; the validated private closure wins; trusted Snap GL, - `graphics-core22`, and exact GNOME-platform roots precede generic in-snap - roots. The extracted-artifact verifier removes the identical unsafe - loader/graphics/shell set before direct helper smoke while preserving + `graphics-core22`, the core22 base x64 root, and exact GNOME-platform roots + precede generic in-snap roots. The core22 base must precede GNOME so its + `libedit.so.2` cannot be replaced by the older copy requiring + `libtinfo.so.5`. The extracted-artifact verifier removes the identical + unsafe loader/graphics/shell set before direct helper smoke while preserving feature/debug selectors such as `LIBGL_ALWAYS_SOFTWARE`. Snap fixes the wrapper `PATH`, removes exported `BASH_FUNC_*` functions, and launches probe/playback through the regular executable diff --git a/CLAUDE.md b/CLAUDE.md index 56652a1ac..3f5e5db1d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -657,10 +657,12 @@ engine` (restart required) or links `libGL.so.1`, and probe/playback share a sanitized loader environment in which ambient audit, preload, library, graphics-driver, and shell-startup overrides are removed; the validated private closure plus trusted host GL, - graphics-content, and exact GNOME-platform roots have explicit precedence. - The extracted-artifact verifier removes the identical unsafe - loader/graphics/shell set before direct helper smoke while preserving - selectors such as `LIBGL_ALWAYS_SOFTWARE`. Snap fixes the wrapper `PATH`, + graphics-content, core22 base x64, and exact GNOME-platform roots have + explicit precedence. The core22 base stays ahead of GNOME so the older + `libedit.so.2` requiring `libtinfo.so.5` cannot shadow the base ABI. The + extracted-artifact verifier removes the identical unsafe loader/graphics/ + shell set before direct helper smoke while preserving selectors such as + `LIBGL_ALWAYS_SOFTWARE`. Snap fixes the wrapper `PATH`, removes exported `BASH_FUNC_*` functions, and launches probe/playback through the regular executable `$SNAP/graphics/bin/graphics-core22-provider-wrapper`; a missing or diff --git a/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.spec.ts b/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.spec.ts index 16da423e3..168ccc144 100644 --- a/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.spec.ts +++ b/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.spec.ts @@ -74,7 +74,7 @@ describe('createLinuxFrameCopyHelperEnvironment', () => { ).toEqual(GRAPHICS_SELECTOR_ENVIRONMENT); }); - it('keeps trusted Snap GL roots ahead of generic Snap libraries', () => { + it('keeps trusted Snap GL and core22 roots ahead of older and generic libraries', () => { const snapRoot = '/snap/iptvnator/42'; const nativeDir = path.join( snapRoot, @@ -220,6 +220,7 @@ describe('createLinuxFrameCopyHelperEnvironment', () => { 'x86_64-linux-gnu', 'vdpau' ), + '/usr/lib/x86_64-linux-gnu', path.join( snapRoot, 'gnome-platform', @@ -324,6 +325,7 @@ describe('createLinuxFrameCopyHelperEnvironment', () => { 'x86_64-linux-gnu', 'vdpau' ), + '/usr/lib/x86_64-linux-gnu', path.join(snapRoot, 'lib'), path.join(snapRoot, 'usr', 'lib'), path.join(snapRoot, 'lib', 'x86_64-linux-gnu'), diff --git a/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.ts b/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.ts index fb9715748..ecf7d5c08 100644 --- a/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.ts +++ b/apps/electron-backend/src/app/services/embedded-mpv-frame-copy-runtime/helper-environment.ts @@ -7,6 +7,7 @@ const TRUSTED_SNAP_EGL_VENDOR_ROOT = '/var/lib/snapd/lib/glvnd/egl_vendor.d'; const SNAP_DESKTOP_RUNTIME_DIRECTORY = 'gnome-platform'; const SNAP_GRAPHICS_RUNTIME_DIRECTORY = 'graphics'; const SNAP_X64_LIBRARY_TRIPLET = 'x86_64-linux-gnu'; +const TRUSTED_SNAP_BASE_LIBRARY_ROOT = '/usr/lib/x86_64-linux-gnu'; const TRUSTED_SNAP_HELPER_PATH = '/usr/sbin:/usr/bin:/sbin:/bin'; const TRUSTED_FLATPAK_APP_ID = 'com.fourgray.iptvnator'; const TRUSTED_FLATPAK_APP_ROOT = '/app'; @@ -84,6 +85,8 @@ function getTrustedSnapLibraryPaths( ...snapLibraryPaths, graphicsLibraryRoot, path.join(graphicsLibraryRoot, 'vdpau'), + // The core22 libedit ABI must win over gnome-3-28's libtinfo5 build. + TRUSTED_SNAP_BASE_LIBRARY_ROOT, ...desktopLibraryPaths, path.join(snapRoot, 'lib'), path.join(snapRoot, 'usr', 'lib'), diff --git a/apps/electron-backend/src/app/services/embedded-mpv-frame-copy.adapter.spec.ts b/apps/electron-backend/src/app/services/embedded-mpv-frame-copy.adapter.spec.ts index 4900c9f58..10698bd55 100644 --- a/apps/electron-backend/src/app/services/embedded-mpv-frame-copy.adapter.spec.ts +++ b/apps/electron-backend/src/app/services/embedded-mpv-frame-copy.adapter.spec.ts @@ -351,6 +351,7 @@ describe('EmbeddedMpvFrameCopyAdapter', () => { 'x86_64-linux-gnu', 'vdpau' ), + '/usr/lib/x86_64-linux-gnu', path.join( snapRoot, 'gnome-platform', diff --git a/docs/architecture/embedded-mpv-native.md b/docs/architecture/embedded-mpv-native.md index a2087fa10..156a249e4 100644 --- a/docs/architecture/embedded-mpv-native.md +++ b/docs/architecture/embedded-mpv-native.md @@ -316,12 +316,15 @@ ambient-path assertions and fail-closed application gate stay active. Inside a genuine Snap mount, filtered absolute `SNAP_LIBRARY_PATH` entries below `/var/lib/snapd/lib/gl` follow `native/lib`. The exact `$SNAP/graphics/usr/lib/x86_64-linux-gnu` content-provider roots come next, -followed by the GNOME platform's fixed x64 library, Mesa, DRI, and PulseAudio -roots only when `SNAP_DESKTOP_RUNTIME` resolves exactly to -`$SNAP/gnome-platform`; generic `$SNAP` roots remain last. The helper also -rebuilds the GBM, GL/VA driver, EGL vendor/platform, and Vulkan layer variables -from those trusted roots. Caller-provided triplets, graphics-driver paths, and -out-of-root loader entries are ignored. +followed by the core22 base `/usr/lib/x86_64-linux-gnu`, then the GNOME +platform's fixed x64 library, Mesa, DRI, and PulseAudio roots only when +`SNAP_DESKTOP_RUNTIME` resolves exactly to `$SNAP/gnome-platform`; generic +`$SNAP` roots remain last. Core22 must precede that older desktop content +runtime so its compatible `libedit.so.2` wins instead of the GNOME copy that +requires unavailable `libtinfo.so.5`. The helper also rebuilds the GBM, GL/VA +driver, EGL vendor/platform, and Vulkan layer variables from those trusted +roots. Caller-provided triplets, graphics-driver paths, and out-of-root loader +entries are ignored. Both the bounded probe and playback execute the helper through `$SNAP/graphics/bin/graphics-core22-provider-wrapper`. Before either launch, the app requires the mounted graphics root to be a real directory and the diff --git a/tools/embedded-mpv/README.md b/tools/embedded-mpv/README.md index 57361da99..0c16cc216 100644 --- a/tools/embedded-mpv/README.md +++ b/tools/embedded-mpv/README.md @@ -167,11 +167,14 @@ therefore invokes `flatpak run com.fourgray.iptvnator --embedded-mpv-runtime-probe` instead of executing the helper around the application gate. In a genuine Snap mount, filtered `SNAP_LIBRARY_PATH` GL roots under `/var/lib/snapd/lib/gl` come next, then the fixed x64 -`$SNAP/graphics` roots, then exact `$SNAP/gnome-platform` graphics/audio roots, -and finally generic `$SNAP` library roots. The helper rebuilds GBM, GL/VA -driver, EGL vendor/platform, and Vulkan layer variables from those trusted -locations. A Linux session without the validated cached mode is rejected -before spawn. +`$SNAP/graphics` roots, then the core22 base +`/usr/lib/x86_64-linux-gnu`, exact `$SNAP/gnome-platform` graphics/audio roots, +and finally generic `$SNAP` library roots. Keeping the base ABI ahead of the +older GNOME content runtime prevents its `libedit.so.2` from injecting an +unavailable `libtinfo.so.5` dependency into mesa-core22's software renderer. +The helper rebuilds GBM, GL/VA driver, EGL vendor/platform, and Vulkan layer +variables from those trusted locations. A Linux session without the validated +cached mode is rejected before spawn. Both the bounded probe and playback execute through `$SNAP/graphics/bin/graphics-core22-provider-wrapper`. The graphics mount must be a real directory and the wrapper a regular, non-symlinked, readable