From 424d3f5083ac08100b9aea233b8133ecf54694b8 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 26 Sep 2021 16:51:36 +0300 Subject: tests: add testcase for PT_PHDR VirtAddr corruption A PT_PHDR corruption was previously reported and fixed in [1]: the issue was that the VirtAddr field of the PT_PHDR program header would get overwritten with the file offset of the program header table rather than the virtual address. A testcase for this was also added in [2]. However, the tescase is not included in the Makefile.am regression testsuite and also tries to run a x86_64 prebuilt binary unconditionally, which would not work on other architectures. To fix this, create a standalone testcase for the PT_PHDR VirtAddr field corruption and include it in Makefile.am. In order to reproduce [1], a binary with the following characteristics is needed: - the ELF file type must be ET_DYN - the ELF file must contain a PT_PHDR program header - the file offset and the VirtAddr field of the PT_PHDR program header must be different [1] https://github.com/NixOS/patchelf/pull/243 [2] https://github.com/NixOS/patchelf/commit/8f94e116f3c63afe224f1ec48ccad6f068f835df Signed-off-by: Ovidiu Panait --- tests/Makefile.am | 10 ++++++++-- tests/PR243-reproducer.sh | 13 ------------- tests/phdr-corruption.ld | 16 ++++++++++++++++ tests/phdr-corruption.sh | 21 +++++++++++++++++++++ tests/void.c | 4 ++++ 5 files changed, 49 insertions(+), 15 deletions(-) delete mode 100755 tests/PR243-reproducer.sh create mode 100644 tests/phdr-corruption.ld create mode 100755 tests/phdr-corruption.sh create mode 100644 tests/void.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 6ad76f4..4b8a027 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -39,7 +39,8 @@ src_TESTS = \ no-dynamic-section.sh \ args-from-file.sh \ basic-flags.sh \ - set-empty-rpath.sh + set-empty-rpath.sh \ + phdr-corruption.sh build_TESTS = \ $(no_rpath_arch_TESTS) @@ -104,7 +105,8 @@ check_DATA = libbig-dynstr.debug # - without libtool, only archives (static libraries) can be built by automake # - with libtool, it is difficult to control options # - with libtool, it is not possible to compile convenience *dynamic* libraries :-( -check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so libbuildid.so libtoomanystrtab.so +check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so libbuildid.so libtoomanystrtab.so \ + phdr-corruption.so libbuildid_so_SOURCES = simple.c libbuildid_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-build-id @@ -138,3 +140,7 @@ no_rpath_CFLAGS = contiguous_note_sections_SOURCES = contiguous-note-sections.s contiguous-note-sections.ld contiguous_note_sections_LDFLAGS = -nostdlib -T contiguous-note-sections.ld contiguous_note_sections_CFLAGS = -pie + +phdr_corruption_so_SOURCES = void.c phdr-corruption.ld +phdr_corruption_so_LDFLAGS = -nostdlib -shared -Wl,-Tphdr-corruption.ld +phdr_corruption_so_CFLAGS = diff --git a/tests/PR243-reproducer.sh b/tests/PR243-reproducer.sh deleted file mode 100755 index 5fa4d55..0000000 --- a/tests/PR243-reproducer.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -set -ex -# PR243-reproducer.sh -curl -OLf https://github.com/NixOS/patchelf/files/6501509/ld-linux-x86-64.so.2.tar.gz -curl -OLf https://github.com/NixOS/patchelf/files/6501457/repro.tar.gz -tar fx repro.tar.gz -tar fx ld-linux-x86-64.so.2.tar.gz -chmod +x repro -cp repro repro.orig -../src/patchelf --set-interpreter ./ld-linux-x86-64.so.2 ./repro -patchelf --print-interpreter repro.orig -readelf -a repro > /dev/null -./repro diff --git a/tests/phdr-corruption.ld b/tests/phdr-corruption.ld new file mode 100644 index 0000000..6cf322c --- /dev/null +++ b/tests/phdr-corruption.ld @@ -0,0 +1,16 @@ +PHDRS +{ + headers PT_PHDR PHDRS; + text PT_LOAD FILEHDR PHDRS; + interp PT_INTERP ; +} + +SECTIONS +{ + . = SIZEOF_HEADERS; + . = ALIGN(4); + + . = . + 0x1000; + .interp : { *(.interp) } :text :interp + .text : { *(.text) } :text +} diff --git a/tests/phdr-corruption.sh b/tests/phdr-corruption.sh new file mode 100755 index 0000000..0a36882 --- /dev/null +++ b/tests/phdr-corruption.sh @@ -0,0 +1,21 @@ +#! /bin/sh -e + +PATCHELF="../src/patchelf" +SONAME="phdr-corruption.so" +SCRATCH="scratch/$(basename $0 .sh)" +SCRATCH_SO="${SCRATCH}/${SONAME}" + +rm -rf "${SCRATCH}" +mkdir -p "${SCRATCH}" +cp "${SONAME}" "${SCRATCH}" + +"${PATCHELF}" --set-rpath "$(pwd)" "${SCRATCH_SO}" + +# Check for PT_PHDR entry VirtAddr corruption +readelfData=$(readelf -l "${SCRATCH_SO}" 2>&1) + +if [ $(echo "$readelfData" | grep --count "PHDR") != 1 ]; then + # Triggered if PHDR errors appear on stderr + echo "ERROR: Unexpected number of occurences of PHDR in readelf results!" + exit 1 +fi diff --git a/tests/void.c b/tests/void.c new file mode 100644 index 0000000..a46866d --- /dev/null +++ b/tests/void.c @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} -- cgit v1.2.1