From 65cdee904431d16668f95d816a495bc35a05a192 Mon Sep 17 00:00:00 2001 From: Breno Rodrigues Guimaraes Date: Mon, 20 Mar 2023 07:48:00 -0300 Subject: Resize segment mapping rewritten sections if needed --- src/patchelf.cc | 12 ++++++++++++ tests/Makefile.am | 3 ++- tests/short-first-segment.gz | Bin 0 -> 170253 bytes tests/short-first-segment.sh | 31 +++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100755 tests/short-first-segment.gz create mode 100755 tests/short-first-segment.sh diff --git a/src/patchelf.cc b/src/patchelf.cc index ee00918..82b4b46 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -1030,6 +1030,18 @@ void ElfFile::rewriteSectionsExecutable() firstPage -= neededPages * getPageSize(); startOffset += neededPages * getPageSize(); + } else { + Elf_Off rewrittenSectionsOffset = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr); + for (auto& phdr : phdrs) + if (rdi(phdr.p_type) == PT_LOAD && + rdi(phdr.p_offset) <= rewrittenSectionsOffset && + rdi(phdr.p_offset) + rdi(phdr.p_filesz) > rewrittenSectionsOffset && + rdi(phdr.p_filesz) < neededSpace) + { + wri(phdr.p_filesz, neededSpace); + wri(phdr.p_memsz, neededSpace); + break; + } } diff --git a/tests/Makefile.am b/tests/Makefile.am index 5dba804..a68d2e2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -50,6 +50,7 @@ src_TESTS = \ rename-dynamic-symbols.sh \ overlapping-segments-after-rounding.sh \ shared-rpath.sh \ + short-first-segment.sh \ empty-note.sh build_TESTS = \ @@ -58,7 +59,7 @@ build_TESTS = \ TESTS = $(src_TESTS) $(build_TESTS) EXTRA_DIST = no-rpath-prebuild $(src_TESTS) no-rpath-prebuild.sh invalid-elf endianness empty-note \ - overlapping-segments-after-rounding + overlapping-segments-after-rounding short-first-segment.gz TESTS_ENVIRONMENT = PATCHELF_DEBUG=1 STRIP=$(STRIP) OBJDUMP=$(OBJDUMP) READELF=$(READELF) OBJCOPY=$(OBJCOPY) diff --git a/tests/short-first-segment.gz b/tests/short-first-segment.gz new file mode 100755 index 0000000..c7ffdca Binary files /dev/null and b/tests/short-first-segment.gz differ diff --git a/tests/short-first-segment.sh b/tests/short-first-segment.sh new file mode 100755 index 0000000..07019fc --- /dev/null +++ b/tests/short-first-segment.sh @@ -0,0 +1,31 @@ +#! /bin/sh -e + +PATCHELF=$(readlink -f "../src/patchelf") +SCRATCH="scratch/$(basename "$0" .sh)" +READELF=${READELF:-readelf} + +EXEC_NAME="short-first-segment" + +if ! gzip --version >/dev/null; then + echo "skipping test: gzip not found" + exit 77 +fi + +if test "$(uname -i)" != x86_64 || test "$(uname)" != Linux; then + echo "skipping test: not supported on x86_64 Linux" + exit 77 +fi + +rm -rf "${SCRATCH}" +mkdir -p "${SCRATCH}" + +gzip -c -d "${srcdir:?}/${EXEC_NAME}.gz" > "${SCRATCH}/${EXEC_NAME}" +cd "${SCRATCH}" + +ldd "${EXEC_NAME}" + +${PATCHELF} --add-rpath lalalalalalalala --output modified1 "${EXEC_NAME}" +ldd modified1 + +${PATCHELF} --add-needed "libXcursor.so.1" --output modified2 modified1 +ldd modified2 -- cgit v1.2.1