diff options
author | Ovidiu Panait <ovpanait@gmail.com> | 2021-09-26 16:51:36 +0300 |
---|---|---|
committer | Ovidiu Panait <ovpanait@gmail.com> | 2021-09-26 19:09:55 +0300 |
commit | 424d3f5083ac08100b9aea233b8133ecf54694b8 (patch) | |
tree | 8e5ae309aa1c94918c7e46cbe95ce857f5edb29c | |
parent | 3cfd9a6637a3a1f102839eedff69cab3e0a24985 (diff) | |
download | patchelf-424d3f5083ac08100b9aea233b8133ecf54694b8.tar.gz |
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 <ovpanait@gmail.com>
-rw-r--r-- | tests/Makefile.am | 10 | ||||
-rwxr-xr-x | tests/PR243-reproducer.sh | 13 | ||||
-rw-r--r-- | tests/phdr-corruption.ld | 16 | ||||
-rwxr-xr-x | tests/phdr-corruption.sh | 21 | ||||
-rw-r--r-- | tests/void.c | 4 |
5 files changed, 49 insertions, 15 deletions
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; +} |