Skip to content

capsule-capture-libs treats $ORIGIN literally in DT_RUNPATH dependency lookup #837

Description

@tracyliving

Your system information

  • Steam Runtime Version: Steam Linux Runtime 3.0 (sniper) 3.0.20260608.242788; steam-runtime-tools / pressure-vessel 0.20260601.0
  • Distribution (e.g. Ubuntu 18.04): Ubuntu 26.04 LTS
  • Link to your full system information (Help -> Steam Runtime Diagnostics) in a Gist: https://gist.github.com/tracyliving/e82c7ab2fc0377924a1dad785c4bd333 (home directory redacted)
  • Have you checked for system updates?: Steam verified its installation; host package updates were not checked because the standalone reproducer does not depend on the graphics stack
  • What compatibility tool are you using?: Steam Linux Runtime 3.0 (sniper); the reproducer also invokes its capsule-capture-libs directly
  • What versions are listed in steamapps/common/SteamLinuxRuntime/VERSIONS.txt? Not installed
  • What versions are listed in steamapps/common/SteamLinuxRuntime_soldier/VERSIONS.txt? Not installed
  • What versions are listed in steamapps/common/SteamLinuxRuntime_sniper/VERSIONS.txt? depot 3.0.20260608.242788, pressure-vessel 0.20260601.0, sniper 3.0.20260608.242788
  • What versions are listed in steamapps/common/SteamLinuxRuntime_4/VERSIONS.txt? depot 4.0.20260608.242786, pressure-vessel 0.20260601.0, steamrt4 4.0.20260608.242786

Please describe your issue in as much detail as possible:

x86_64-linux-gnu-capsule-capture-libs recognizes a DSO's DT_RUNPATH=$ORIGIN, but appears to treat $ORIGIN as a literal directory name instead of expanding it relative to the DSO containing the RUNPATH.

A minimal layer DSO has:

NEEDED  Shared library: [libcapsule-origin-helper.so.1]
RUNPATH Library runpath: [$ORIGIN]

The layer and helper are in the same directory. A normal dlopen(..., RTLD_NOW) succeeds and calls into the helper (result=42). The same layer fails dependency resolution in capsule-capture-libs.

Relevant debug output:

_dso_iterate_sections: .../libcapsule-origin-layer.so.1 DT_RUNPATHs "$ORIGIN"
search_ldpath: searching for libcapsule-origin-helper.so.1 in $ORIGIN (prefix: /)
search_ldpath: examining /$ORIGIN/libcapsule-origin-helper.so.1
error: code 2: Missing dependencies: Could not find
       "libcapsule-origin-helper.so.1" in LD_LIBRARY_PATH (unset),
       ld.so.cache, DT_RUNPATH or fallback ...

I expected $ORIGIN to resolve to the directory containing libcapsule-origin-layer.so.1, matching the dynamic loader. This affects importing host Vulkan layers that have private sibling dependencies.

Sanitized standalone reproducer and observed output:
https://gist.github.com/tracyliving/43714c213b92c677aee924697c97f345

Workarounds include adding the sibling directory to LD_LIBRARY_PATH, using an absolute RUNPATH, or removing the DT_NEEDED edge and loading the sibling explicitly. PRESSURE_VESSEL_IMPORT_VULKAN_LAYERS=0 bypasses this path but disables host Vulkan-layer import, so it is not equivalent behavior.

I found issue #478 while searching, but that concerns non-standard Guix library locations rather than $ORIGIN expansion.

Steps for reproducing this issue:

  1. Clone the reproducer:

    git clone https://gist.github.com/43714c213b92c677aee924697c97f345.git capsule-origin-repro
    cd capsule-origin-repro
  2. Pass the installed Sniper tool to the script:

    sh reproduce.sh \
      "$HOME/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper/pressure-vessel/libexec/steam-runtime-tools-0/x86_64-linux-gnu-capsule-capture-libs"
  3. Observe that the native loader prints result=42, then capsule-capture-libs exits nonzero after examining /$ORIGIN/libcapsule-origin-helper.so.1.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions