rewriteSections: rewrite executables like shared objects (#622)#637
Open
JamieMagee wants to merge 1 commit into
Open
rewriteSections: rewrite executables like shared objects (#622)#637JamieMagee wants to merge 1 commit into
JamieMagee wants to merge 1 commit into
Conversation
13 tasks
Member
|
Could you resolve conflicts? |
e4ae562 to
b01116e
Compare
Member
Author
|
@domenkozar done! |
b01116e to
cf2ebf3
Compare
Patching a non-PIE (ET_EXEC) binary so that the program header table grows made the executable rewrite path shift every LOAD segment's p_vaddr down by one or more pages, producing LOAD segments below the input's lowest p_vaddr. On systems that enforce vm.mmap_min_addr at that floor (e.g. riscv64-linux at 0x10000) the kernel rejects the fixed-address mmap at exec time and the patched binary fails to load. Shared objects already avoid this: rewriteSectionsLibrary appends the rewritten sections in a fresh PT_LOAD at the end of the file, leaving every existing LOAD's vaddr unchanged. Route ET_EXEC through the same path and drop the executable-specific rewriteSectionsExecutable. The program header table stays at its canonical front offset, which executables need: loaders such as qemu-user (and the dynamic linkers it runs) compute AT_PHDR as (lowest LOAD vaddr) + e_phoff, so a PHT moved to a tail segment with a different vaddr/offset skew would be found at the wrong address. Also harden buildResolutionCache to report an already-present cache note loudly even when .dynamic/.dynstr are too malformed to parse, instead of erroring on the section first. Adds no-vaddr-underrun.sh (asserts the post-patch lowest LOAD p_vaddr is not below the pre-patch value on a non-PIE x86_64 binary). build-resolution-cache-no-pie.sh bakes a link-time DT_RPATH into the main-no-pie fixture so it can build its layout without patchelf. Closes NixOS#622
cf2ebf3 to
bd12049
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Patching a non-PIE (
ET_EXEC) binary so the program header table grows made the executable rewrite path shift every LOAD segment'sp_vaddrdown, producing LOAD segments below the input's lowestp_vaddr. Wherevm.mmap_min_addris set to that floor (e.g. riscv64-linux at0x10000), the kernel rejects the fixed-address mmap and the patched binary fails to load.Shared objects already avoid this:
rewriteSectionsLibraryappends the rewritten sections in a freshPT_LOADat the end of the file, leaving existing LOAD vaddrs unchanged. This routesET_EXECthrough the same path and removesrewriteSectionsExecutable.Keeping the program header table at its canonical front offset matters for executables: loaders like qemu-user compute
AT_PHDRas(lowest LOAD vaddr) + e_phoff, so a PHT moved into a tail segment is found at the wrong address.Also hardens
--build-resolution-cacheto fail loudly on an already-present note even when.dynamic/.dynstrare unparseable.Tested with
no-vaddr-underrun.shand under qemu-user (x86_64, aarch64); on the nixpkgs riscv64 bootstrap-tools gcc the load base stays at0x10000instead of dropping to0xe000. CI is green across the emulated arches.Closes #622