Skip to content

fix(relinker): validate every entry of the Linux run path - #10607

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
roboterspinne:fix/relinker-linux-run-path
Oct 26, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
roboterspinne:fix/relinker-linux-run-path

Conversation

@roboterspinne

Copy link
Copy Markdown
Contributor

What

Linux was the only target that wrote --rpath into the output without checking its entries.

Tested

Ubuntu 24.04 x86_64, glibc 2.39, relinker-only Release build (-DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON); synthetic fixtures only, no title or homebrew.

  • ctest --test-dir build-relinker -j4: 243/243 passed. linux_dynamic_strings and guest_runpath fail against the main binary (('', [], 0, ...) and ('$ORIGIN/libs:', 0, ...), both with exit 0) and pass with this change.
  • With guest modules, --rpath '$ORIGIN:relative/libs' and --rpath '$ORIGIN/libs:' relink with exit 0 on main and now exit 2 with Guest Linux run path must be absolute or begin with $ORIGIN; --rpath '$ORIGIN:$ORIGIN/libs' still exits 0.
  • glibc behaviour behind the check, with a gcc-built program and library: RUNPATH [nonexist:] and [nonexist::x] find libdata.so only when the program is started inside the directory that holds it (exit 8 there, cannot open shared object file elsewhere); RUNPATH [] finds it in neither place.
  • python3 tools/check_conventions.py --base upstream/main with this title and description passed.
  • Not tested on Windows or macOS; the changed code is host-independent and CI runs both tests on all three hosts.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes (Claude Code)

LinuxElfPatcher wrote --rpath into DT_RUNPATH unchanged, so an empty
entry (an empty value, a leading or trailing colon, or a double colon)
reached the output, where glibc searches the working directory for it,
while the macOS and Windows outputs reject empty run paths. The guest
module rule that each entry is absolute or begins with $ORIGIN only
looked at the start of the whole value, so "$ORIGIN/libs:" or
"$ORIGIN:relative/libs" passed. The Linux patcher now rejects an empty
entry with the message the macOS patcher uses, the guest rule checks
every colon-separated entry, and USAGE.md says so.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed head 5362dca. The Linux patcher rejects empty run-path components before writing output, and guest modules now validate every colon-separated component while preserving the accepted absolute and $ORIGIN forms. The added cases cover empty, leading, trailing, and interior components on default and lazy-binding Linux outputs, plus invalid guest lists. Eligibility, conventions, intake, labels, Linux/Windows/macOS relinker jobs, and relinker ASan pass; full product Linux/Windows jobs are skipped for this relinker-focused change. The described Ubuntu/glibc behavior and relinker-only CTest results are author-reported; I did not reproduce them locally.

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 3786 docs/user/USAGE.md
PR 5021 docs/user/USAGE.md
PR 5925 docs/user/USAGE.md
PR 6171 docs/user/USAGE.md
PR 6924 docs/user/USAGE.md
PR 7642 docs/user/USAGE.md
PR 9345 docs/user/USAGE.md
PR 9508 docs/user/USAGE.md
PR 10193 docs/user/USAGE.md

@oneandonlydean oneandonlydean self-assigned this Oct 25, 2026
@wachi35676

Copy link
Copy Markdown
Contributor

Tested head 5362dca merged onto main aeff26b (clean) on Windows 11 (Ryzen 5 9600X), WinLibs GCC 15.2.0, Release.

  • guest_runpath, windows_runpath, linux_dynamic_strings: 3/3 pass.
  • Negative control: with main's LinuxElfPatcher.cpp and GuestModuleBuilder.cpp, both new cases fail:
    • linux_dynamic_strings at ('', [], 0, ...): --rpath "" converts with exit 0.
    • guest_runpath at ('$ORIGIN/libs:', 0, ...).
  • Four real homebrew eboots converted with the default run path to Windows, macOS and Linux all exit 0, with output byte-identical to main's.

AI-assisted: yes (Claude Code); results above were run on this machine.

@oneandonlydean
oneandonlydean merged commit dbf4f6a into boykopovar:main Oct 26, 2026
13 checks passed
@roboterspinne
roboterspinne deleted the fix/relinker-linux-run-path branch October 26, 2026 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants