Skip to content

fix(relinker): validate translated load segment file ranges - #2068

Closed
deadpoods wants to merge 2 commits into
boykopovar:mainfrom
deadpoods:fix/relinker-file-backed-addresses
Closed

deadpoods wants to merge 2 commits into
boykopovar:mainfrom
deadpoods:fix/relinker-file-backed-addresses

Conversation

@deadpoods

Copy link
Copy Markdown

What

ElfReader::TranslateVirtualAddress could wrap a PT_LOAD file offset and return a location in unrelated input bytes. A synthetic ELF with p_offset=0xfffffffffffff000, p_vaddr=0x2000, p_filesz=0x2000 and DT_STRTAB=0x3600 translates to file offset 0x600 after wrapping. On unmodified main, Linux conversion succeeds and emits DT_NEEDED=libwrongx.prx from those unrelated bytes. The valid control emits libkernel.prx.

Check the selected load segment's complete file range with the existing subtraction-based _rangeFits helper before adding the address displacement. The malformed input now exits 2 with Segment offset out of bounds (offset 0xfffffffffffff000) and creates neither an executable nor a registry. Windows also rejects it in the shared parser, before its existing PE-specific validation.

The ELF gABI, sections 7.1 and 7.2 defines p_offset as the start of a segment's file image and p_filesz as its extent. The check follows the existing ElfReader::ReadSegment contract, which rejects a segment whose complete file range exceeds the input. This deliberately rejects truncated segments even when the requested byte itself is inside the file.

Extend the already registered elf_offsets test with 20 conversions: valid mappings, the first file-backed byte, a segment ending exactly at EOF, wrapping/past-EOF offsets, truncated and oversized extents, an address at the segment's exclusive end, and an empty segment. Invalid cases require exit 2, the expected diagnostic, and no output or registry. Valid Linux controls inspect the emitted dynamic table and dependency name; Windows controls verify successful PE generation. Existing assertions are retained.

This is the deferred file-offset translation gap recorded in #1690. It does not duplicate that PR's symbol-boundary tests or #1272's symbol guard. Open #1087 and #1956 change other ElfReader methods; #1446 bounds RELA tables and #1943 handles Linux layout-address overflow. The audit reviewed all 558 open PRs and current relinker/ELF issues on 9 October 2026; no equivalent implementation was found. No prerequisite is needed.

Tested

macOS 26.6.2 (25G83), x86-64; AppleClang 21.0.0; CMake 4.4.4; Ninja 1.13.2; Python 3.13. Relinker-only Release build, without third-party submodules or system libraries. Base: f145139676a48306681d3a4d5fabf83938759daf, refreshed from upstream main before final review.

  • Built and ran all existing tests before selecting the task: 34/34 passed (37.08 s).
  • Ran the extended elf_offsets against a saved, unmodified baseline binary: failed at translation-offset-wrap, because Linux returned 0 and wrote an executable instead of rejecting the input. All three new valid controls passed in both output modes before that failure.
  • After the fix, focused elf_offsets: passed (1.84 s).
  • Complete patched suite: 34/34 passed (25.10 s); extended elf_offsets took 1.67 s.
  • python3 tools/check_conventions.py --base origin/main --title 'fix(relinker): validate translated load segment file ranges' --body <PR-description-file>: passed.
  • python3 tools/check_test_registration.py ../build-relinker: all five test executables registered.
  • git diff --check and final diff review: passed; two source/test files, three production lines, no added comments, dependencies or investigation files.

Build and test commands from the repository root:

cmake -S . -B ../build-relinker -G Ninja -DCMAKE_BUILD_TYPE=Release -DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON
cmake --build ../build-relinker --parallel 4
ctest --test-dir ../build-relinker --output-on-failure --parallel 4
ctest --test-dir ../build-relinker --output-on-failure -R '^elf_offsets$'

CMake and Ninja were installed only in the task's work folder. Configuration used an explicit CMAKE_MAKE_PROGRAM path to that Ninja executable; the registration check used its directory on PATH.

Limitations: the fixtures inspect Linux ELF and Windows PE output on macOS; compatible-host execution branches in the existing tests do not run here. No native Linux/Windows build, generated-game execution, real title, full system-library build, GPU test, or sanitizer run was performed. This check covers selected segments used by address translation; general load-segment validation and virtual-address-end overflow remain outside this patch.

Checklist

  • Based on current main; no other open PR implements the same fix
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt (no comments added)
  • Unimplemented paths still throw; no silent stubs added
  • No notes, investigation files or images added to the repository
  • New third-party code is a submodule built from source (none added)
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes. OpenAI Codex performed the investigation, implementation, test work and PR drafting. Prepared for human review before submission.

@rmz-24

rmz-24 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Windows run, since the description notes it wasn't tested there: Windows 11 Pro 25H2 (10.0.26200.9457), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release, full build with BUILD_TESTING=ON. b01704e cherry-picked onto current main d70b899 (applies cleanly).

  • elf_offsets passes.
  • Full ctest: 510/510, including the Windows PE execution tests.

AI-assisted: yes

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Closing: a PT_LOAD whose p_offset wraps doesn't occur in a title the console loads, and no real input is shown reaching it. The new rule also refuses truncated segments, which could stop a title that converts today. Please reopen with the title if one hits this.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants