Repository navigation
fix(relinker): reject prefixed system-call instructions - #1935
Conversation
Use the decoded opcode offset when checking forbidden system calls. Add synthetic regressions for prefixed forms, immediate decoys, and the skip option. AI-assisted: Codex. The submitting author is responsible for every changed line.
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed the full two-file diff at 2381e7f. Using the decoder-reported OpcodeOffset makes the four syscall signatures visible after prefixes while preserving the instruction-start diagnostic; the tests also check immediate-byte decoys and the skip option. The Actions API shows this exact head has Build and Conventions runs marked action_required with no jobs, so upstream CI has not run. CONTRIBUTING requires those checks before merge; please request maintainer approval for the fork workflows. I am holding approval until those final checks run.
|
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
AI-assisted: yes |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
|
Verified this against a clean Fixture whose first executable-segment bytes are the instruction, same input through both relinkers:
One thing worth knowing before either of us lands: #2206 changes the same lines of
The composed form classifies at |
|
Thanks rmz-24 for the Windows validation: Thanks StarMrGamer for checking the prefixed cases and the composition requirement. #2206 adds syscall-number diagnostics in the shared scan loop; it does not replace this PR's prefix-aware AI-assisted review and reply. |
|
@Zinebyte Would these 24 additional boundary tests be useful? nyavana@ac6381e Linux CTest: 66/66 passed, with one internal clang-dependent skip. Two mutation checks verified the added coverage. AI-assisted. |
The lookback classifies preceding instructions at their decoded opcode offset, the same place the forbidden-instruction check looks since boykopovar#1935, so a legacy-prefixed mov rax, imm or mov r10, rcx is recognized. The REX byte stays part of the patterns, so mov r8 and mov r8d cannot masquerade as rax loads. Anything unrecognized still stops the inference. Adds prefixed fixtures to both test suites: a prefixed constant stub that must report syscall number 9, and a prefixed clobbered stub that must report no number. AI-assisted: yes. The submitting author is responsible for every changed line.
…-validation fix(relinker): reject prefixed system-call instructions
|
Thanks @nyavana, these look useful! The exact-boundary, out-of-segment byte and truncated-instruction cases add useful coverage. Since #1935 is now merged, a focused test-only follow-up against current main would make sense. The diff was reviewed with AI assistance; I haven't independently run the tests. Appreciate you adding these. |
The lookback classifies preceding instructions at their decoded opcode offset, the same place the forbidden-instruction check looks since boykopovar#1935, so a legacy-prefixed mov rax, imm or mov r10, rcx is recognized. The REX byte stays part of the patterns, so mov r8 and mov r8d cannot masquerade as rax loads. Anything unrecognized still stops the inference. Adds prefixed fixtures to both test suites: a prefixed constant stub that must report syscall number 9, and a prefixed clobbered stub that must report no number. AI-assisted: yes. The submitting author is responsible for every changed line.
What
The relinker checked the first two bytes of each decoded instruction for forbidden system calls. A prefix hid the opcode:
48 0F 05passed validation and produced an executable even though it containsSYSCALL.Check the decoded instruction's
OpcodeOffset()instead. PrefixedSYSCALL,SYSENTER,SYSRETandINT 80hnow fail with the existing error at the instruction's start address. Opcode-like bytes in immediates remain accepted, and--skip-syscall-checkretains its behavior.This addresses the scanner follow-up explicitly left out of #211. No open overlapping fix was found before implementation or on the final search.
CallSiteResolverremains outside this change.Tested
Zorin OS 18.1, Linux x86-64, GCC 13.3.0, CMake 3.28.3, Release, relinker-only build at
f145139676a48306681d3a4d5fabf83938759daf. Build parallelism: 1.executable_segmentsregression fails on the upstream binary: the REX-prefixed syscall is accepted and output is written. It passes with the fix in 0.03 s.0x1801, no output on rejection, immediate-byte decoys, and the explicit skip option.ctest --test-dir build-relinker --output-on-failure --parallel 1: 38/38 passed in 6.44 s; longest test 5.28 s.python3 tools/check_conventions.py --base origin/mainandgit diff --check: passed.Synthetic inputs only. No title or hardware compatibility testing. Windows PE output is inspected on Linux; native Windows/macOS execution and cold shared CI timing were not measured.
Checklist
main; no open overlapping implementation found