summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBreno Rodrigues GuimarĂ£es <brenorg@gmail.com>2023-03-11 11:01:43 -0300
committerGitHub <noreply@github.com>2023-03-11 11:01:43 -0300
commit27cbc89d4830d5ae1fe3a2396f2a6042266895bc (patch)
treea5af48004999c2a1d9ce1a8578b85c86295282a5
parentac212d0e6fb8b741e5a5e9ea61091149103f401c (diff)
parentde3e1f5e11f533d8678474eb9234ba35efa960d6 (diff)
downloadpatchelf-27cbc89d4830d5ae1fe3a2396f2a6042266895bc.tar.gz
Merge pull request #469 from brenoguim/breno.446
Add one extra page to avoid overlapping with next page if its rounded…
-rw-r--r--src/patchelf.cc4
-rw-r--r--tests/Makefile.am4
-rwxr-xr-xtests/overlapping-segments-after-roundingbin0 -> 227896 bytes
-rwxr-xr-xtests/overlapping-segments-after-rounding.sh23
4 files changed, 29 insertions, 2 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc
index 62af389..1a90edb 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -1019,7 +1019,9 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
/* Calculate how many bytes are needed out of the additional pages. */
size_t extraSpace = neededSpace - startOffset;
- unsigned int neededPages = roundUp(extraSpace, getPageSize()) / getPageSize();
+ // Always give one extra page to avoid colliding with segments that start at
+ // unaligned addresses and will be rounded down when loaded
+ unsigned int neededPages = 1 + roundUp(extraSpace, getPageSize()) / getPageSize();
debug("needed pages is %d\n", neededPages);
if (neededPages * getPageSize() > firstPage)
error("virtual address space underrun!");
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4ae540a..0b648f8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -48,6 +48,7 @@ src_TESTS = \
print-execstack.sh \
modify-execstack.sh \
rename-dynamic-symbols.sh \
+ overlapping-segments-after-rounding.sh \
empty-note.sh
build_TESTS = \
@@ -55,7 +56,8 @@ build_TESTS = \
TESTS = $(src_TESTS) $(build_TESTS)
-EXTRA_DIST = no-rpath-prebuild $(src_TESTS) no-rpath-prebuild.sh invalid-elf endianness empty-note
+EXTRA_DIST = no-rpath-prebuild $(src_TESTS) no-rpath-prebuild.sh invalid-elf endianness empty-note \
+ overlapping-segments-after-rounding
TESTS_ENVIRONMENT = PATCHELF_DEBUG=1 STRIP=$(STRIP) OBJDUMP=$(OBJDUMP) READELF=$(READELF) OBJCOPY=$(OBJCOPY)
diff --git a/tests/overlapping-segments-after-rounding b/tests/overlapping-segments-after-rounding
new file mode 100755
index 0000000..ecad537
--- /dev/null
+++ b/tests/overlapping-segments-after-rounding
Binary files differ
diff --git a/tests/overlapping-segments-after-rounding.sh b/tests/overlapping-segments-after-rounding.sh
new file mode 100755
index 0000000..d7c87b1
--- /dev/null
+++ b/tests/overlapping-segments-after-rounding.sh
@@ -0,0 +1,23 @@
+#! /bin/sh -e
+
+PATCHELF=$(readlink -f "../src/patchelf")
+SCRATCH="scratch/$(basename "$0" .sh)"
+READELF=${READELF:-readelf}
+
+EXEC_NAME="overlapping-segments-after-rounding"
+
+if test "$(uname -i)" = x86_64 && test "$(uname)" = Linux; then
+ rm -rf "${SCRATCH}"
+ mkdir -p "${SCRATCH}"
+
+ cp "${srcdir}/${EXEC_NAME}" "${SCRATCH}/"
+ cd "${SCRATCH}"
+
+ ${PATCHELF} --force-rpath --remove-rpath --output modified1 "${EXEC_NAME}"
+
+ ldd modified1
+
+ ${PATCHELF} --force-rpath --set-rpath "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" --output modified2 modified1
+
+ ldd modified2
+fi