diff --git a/ChangeLog.md b/ChangeLog.md index 1f408ab1..bed72b01 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,51 @@ -## Release History +# Release History + +## 0.16.2 (Yet to be released) + +The release combines the 0.15.1 through 0.15.4 backports with 0.16.1. + +* Code quality and infra changes just like 0.15.{1,2} +* Update to a later glibc `elf.h`, just like 0.15.4 + +## 0.16.1 (October 28, 2022) + +This release only fixes the incorrect reported version by the 0.16.0 release. + +## 0.16.0 (October 27, 2022) + +Changes from 0.15.3: + +* Add `--print-os-abi` and `--set-os-abi` options by @dmsck in https://github.com/NixOS/patchelf/pull/381 +* Sync `.note.gnu.property` to `PT_GNU_PROPERTY` by @Bo98 in https://github.com/NixOS/patchelf/pull/414 +* Rework file shifting to avoid sections crossing multiple segments by @Bo98 in https://github.com/NixOS/patchelf/pull/415 + +(These notes are the remainder of 0.16.0 that was not backported to 0.15.3. +Originally, 0.16.0 was branched from 0.15.0, and those changes were fresh in this release, having never been backported.) + +## 0.15.5 (August 12, 2025) + +Bugfix backports from 0.18.0: + +* Adjust `roundUp` for 0 as input by @cgzones in https://github.com/NixOS/patchelf/pull/466 + +Bugfix backports from 0.17.{0, 1}: + +* Fix page size constants for Itanium and SPARC. +* Fix Out-of-bounds read in the function `modifySoname` by @yairKoskas in https://github.com/NixOS/patchelf/pull/451 + +## 0.15.4 (August 12, 2025) + +* Update to a later glibc `elf.h`. + + This should not result in any behavioral changes, except for possibly better architecture-specific support. + +## 0.15.3 (August 12, 2025) + +This is a backport release made from the simplest fixes from 0.16.0. + +* Handle `glibc-hwcaps` on `ppc64le` on CentOS/RHEL/Rocky 8 for `tests/replace-add-needed.sh` (fixes #406) by @robert-scheck in https://github.com/NixOS/patchelf/pull/407 +* Fix Out-of-bounds read in the function `modifyRPath` by @xiaoxiaoafeifei in https://github.com/NixOS/patchelf/pull/419 +* Fix out of bounds access when increasing program header table by @Bo98 in https://github.com/NixOS/patchelf/pull/411 ## 0.15.2 (August 12, 2025) @@ -18,13 +65,13 @@ The behavior of this version should be essentially the same as 0.15.0. ## 0.15.0 (July 16, 2022) -* Add --add-debug option by @deadw00d in https://github.com/NixOS/patchelf/pull/367 -* Add O_BINARY flag when opening files to allow compilation for Windows by @JagoGyselinck in https://github.com/NixOS/patchelf/pull/372 -* Document --print-needed by @klemensn in https://github.com/NixOS/patchelf/pull/375 +* Add `--add-debug` option by @deadw00d in https://github.com/NixOS/patchelf/pull/367 +* Add `O_BINARY flag` when opening files to allow compilation for Windows by @JagoGyselinck in https://github.com/NixOS/patchelf/pull/372 +* Document `--print-needed` by @klemensn in https://github.com/NixOS/patchelf/pull/375 * modifyRPath: return early if new and old rpath are empty by @ehmry in https://github.com/NixOS/patchelf/pull/376 -* Add comment explaining calculation for DT_MIPS_RLD_MAP_REL by @amjoseph-nixpkgs in https://github.com/NixOS/patchelf/pull/379 -* Add --no-sort option by @amjoseph-nixpkgs in https://github.com/NixOS/patchelf/pull/378 -* Handle DT_MIPS_XHASH and .MIPS.xhash by @amjoseph-nixpkgs in https://github.com/NixOS/patchelf/pull/380 +* Add comment explaining calculation for `DT_MIPS_RLD_MAP_REL` by @amjoseph-nixpkgs in https://github.com/NixOS/patchelf/pull/379 +* Add `--no-sort option` by @amjoseph-nixpkgs in https://github.com/NixOS/patchelf/pull/378 +* Handle `DT_MIPS_XHASH` and `.MIPS.xhash` by @amjoseph-nixpkgs in https://github.com/NixOS/patchelf/pull/380 ## 0.14.5 (February 21, 2022) @@ -36,7 +83,7 @@ The behavior of this version should be essentially the same as 0.15.0. * Allow multiple modifications in same call by @fzakaria in https://github.com/NixOS/patchelf/pull/361 * Add support to build with musl by @fzakaria in https://github.com/NixOS/patchelf/pull/362 * Fix typo: s/folllow/follow/ by @bjornfor in https://github.com/NixOS/patchelf/pull/366 -* mips: fix incorrect polarity on dyn_offset; closes #364 by @a-m-joseph in https://github.com/NixOS/patchelf/pull/365 +* mips: fix incorrect polarity on `dyn_offset`; closes #364 by @a-m-joseph in https://github.com/NixOS/patchelf/pull/365 ## 0.14.3 (December 05, 2021) @@ -55,13 +102,13 @@ The behavior of this version should be essentially the same as 0.15.0. Changes compared to 0.13: * Bug fixes: - - Fix corrupted library names when using --replace-needed multiple times + - Fix corrupted library names when using `--replace-needed` multiple times - Fix setting an empty rpath - - Don't try to parse .dynamic section of type NOBITS - - Fix use-after-free in normalizeNoteSegments - - Correct EINTR handling in writeFile - - MIPS: Adjust PT_MIPS_ABIFLAGS segment and DT_MIPS_RLD_MAP_REL dynamic section if present - - Fix binaries without .gnu.hash section + - Don't try to parse `.dynamic section` of type `NOBITS` + - Fix use-after-free in `normalizeNoteSegments` + - Correct `EINTR` handling in writeFile + - MIPS: Adjust `PT_MIPS_ABIFLAGS` segment and `DT_MIPS_RLD_MAP_REL` dynamic section if present + - Fix binaries without `.gnu.hash` section * Support loongarch architecture * Remove limits on output file size for elf files * Allow reading rpath from file @@ -72,12 +119,12 @@ Changes compared to 0.13: * Bug fixes: - fix setting empty rpath - use memcpy instead of strcpy to set rpath - - Don't try to parse .dynamic section of type NOBITS - - fix use-after-free in normalizeNoteSegments - - correct EINTR handling in writeFile - - Adjust PT_MIPS_ABIFLAGS segment if present - - Adjust DT_MIPS_RLD_MAP_REL dynamic section entry if present - - fix binaries without .gnu.hash section + - Don't try to parse `.dynamic section` of type `NOBITS` + - fix use-after-free in `normalizeNoteSegments` + - correct `EINTR` handling in writeFile + - Adjust `PT_MIPS_ABIFLAGS` segment if present + - Adjust `DT_MIPS_RLD_MAP_REL` dynamic section entry if present + - fix binaries without `.gnu.hash` section ## 0.13 (August 5, 2021) @@ -105,7 +152,7 @@ Changes compared to 0.13: * Many bug fixes. Please refer to the Git commit log: - https://github.com/NixOS/patchelf/commits/master + https://github.com/NixOS/patchelf/commits/0.10 This release has contributions from Adam Trhoň, Benjamin Hipple, Bernardo Ramos, Bjørn Forsman, Domen Kožar, Eelco Dolstra, Ezra @@ -117,7 +164,7 @@ Changes compared to 0.13: * Lots of new features. Please refer to the Git commit log: - https://github.com/NixOS/patchelf/commits/master + https://github.com/NixOS/patchelf/commits/0.9 This release has contributions from Aaron D. Marasco, Adrien Devresse, Alexandre Pretyman, Changli Gao, Chingis Dugarzhapov, @@ -134,7 +181,7 @@ Changes compared to 0.13: * Rewrite section indices in symbol tables. This for instance allows gdb to show proper backtraces. -* Added `--remove-needed' option. +* Added `--remove-needed` option. ## 0.6 (November 7, 2011) @@ -150,7 +197,7 @@ Changes compared to 0.13: * Various bugfixes. -* `--force-rpath' now deletes the DT_RUNPATH if it is present. +* `--force-rpath` now deletes the `DT_RUNPATH` if it is present. ## 0.4 (June 4, 2008) @@ -160,18 +207,18 @@ Changes compared to 0.13: * FreeBSD support. -* `--set-rpath', `--shrink-rpath' and `--print-rpath' now prefer - DT_RUNPATH over DT_RPATH, which is obsolete. When updating, if both - are present, both are updated. If only DT_RPATH is present, it is - converted to DT_RUNPATH unless `--force-rpath' is specified. If - neither is present, a DT_RUNPATH is added unless `--force-rpath' is - specified, in which case a DT_RPATH is added. +* `--set-rpath`, `--shrink-rpath` and `--print-rpath` now prefer + `DT_RUNPATH` over `DT_RPATH`, which is obsolete. When updating, if both + are present, both are updated. If only `DT_RPATH` is present, it is + converted to `DT_RUNPATH` unless `--force-rpath` is specified. If + neither is present, a `DT_RUNPATH` is added unless `--force-rpath` is + specified, in which case a `DT_RPATH` is added. ## 0.3 (May 24, 2007) -* Support for 64-bit ELF binaries (such as on x86_64-linux). +* Support for 64-bit ELF binaries (such as on `x86_64-linux`). -* Support for big-endian ELF binaries (such as on powerpc-linux). +* Support for big-endian ELF binaries (such as on `powerpc-linux`). * Various bugfixes. diff --git a/src/elf.h b/src/elf.h index 920e6891..89fc8021 100644 --- a/src/elf.h +++ b/src/elf.h @@ -1,5 +1,5 @@ /* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-2022 Free Software Foundation, Inc. + Copyright (C) 1995-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -210,7 +210,7 @@ typedef struct #define EM_68HC12 53 /* Motorola M68HC12 */ #define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */ #define EM_PCP 55 /* Siemens PCP */ -#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NCPU 56 /* Sony nCPU embedded RISC */ #define EM_NDR1 57 /* Denso NDR1 microprocessor */ #define EM_STARCORE 58 /* Motorola Start*Core processor */ #define EM_ME16 59 /* Toyota ME16 processor */ @@ -559,7 +559,7 @@ typedef struct /* Possible bitmasks for si_flags. */ #define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-through symbol for translator */ #define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ #define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy loaded */ @@ -728,6 +728,7 @@ typedef struct #define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ #define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ #define PT_GNU_PROPERTY 0x6474e553 /* GNU property */ +#define PT_GNU_SFRAME 0x6474e554 /* SFrame segment. */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ @@ -1223,6 +1224,9 @@ typedef struct #define AT_HWCAP2 26 /* More machine-dependent hints about processor capabilities. */ +#define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size. */ +#define AT_RSEQ_ALIGN 28 /* rseq allocation alignment. */ + #define AT_EXECFN 31 /* Filename of executable. */ /* Pointer to the global system page used for system calls and other @@ -3998,8 +4002,11 @@ enum #define R_RISCV_SET32 56 #define R_RISCV_32_PCREL 57 #define R_RISCV_IRELATIVE 58 +#define R_RISCV_PLT32 59 +#define R_RISCV_SET_ULEB128 60 +#define R_RISCV_SUB_ULEB128 61 -#define R_RISCV_NUM 59 +#define R_RISCV_NUM 62 /* RISC-V specific values for the st_other field. */ #define STO_RISCV_VARIANT_CC 0x80 /* Function uses variant calling @@ -4159,6 +4166,55 @@ enum #define R_LARCH_GNU_VTINHERIT 57 #define R_LARCH_GNU_VTENTRY 58 +/* reserved 59-63 */ + +#define R_LARCH_B16 64 +#define R_LARCH_B21 65 +#define R_LARCH_B26 66 +#define R_LARCH_ABS_HI20 67 +#define R_LARCH_ABS_LO12 68 +#define R_LARCH_ABS64_LO20 69 +#define R_LARCH_ABS64_HI12 70 +#define R_LARCH_PCALA_HI20 71 +#define R_LARCH_PCALA_LO12 72 +#define R_LARCH_PCALA64_LO20 73 +#define R_LARCH_PCALA64_HI12 74 +#define R_LARCH_GOT_PC_HI20 75 +#define R_LARCH_GOT_PC_LO12 76 +#define R_LARCH_GOT64_PC_LO20 77 +#define R_LARCH_GOT64_PC_HI12 78 +#define R_LARCH_GOT_HI20 79 +#define R_LARCH_GOT_LO12 80 +#define R_LARCH_GOT64_LO20 81 +#define R_LARCH_GOT64_HI12 82 +#define R_LARCH_TLS_LE_HI20 83 +#define R_LARCH_TLS_LE_LO12 84 +#define R_LARCH_TLS_LE64_LO20 85 +#define R_LARCH_TLS_LE64_HI12 86 +#define R_LARCH_TLS_IE_PC_HI20 87 +#define R_LARCH_TLS_IE_PC_LO12 88 +#define R_LARCH_TLS_IE64_PC_LO20 89 +#define R_LARCH_TLS_IE64_PC_HI12 90 +#define R_LARCH_TLS_IE_HI20 91 +#define R_LARCH_TLS_IE_LO12 92 +#define R_LARCH_TLS_IE64_LO20 93 +#define R_LARCH_TLS_IE64_HI12 94 +#define R_LARCH_TLS_LD_PC_HI20 95 +#define R_LARCH_TLS_LD_HI20 96 +#define R_LARCH_TLS_GD_PC_HI20 97 +#define R_LARCH_TLS_GD_HI20 98 +#define R_LARCH_32_PCREL 99 +#define R_LARCH_RELAX 100 + +/* ARC specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_ARC_MACH_MSK 0x000000ff +#define EF_ARC_OSABI_MSK 0x00000f00 +#define EF_ARC_ALL_MSK (EF_ARC_MACH_MSK | EF_ARC_OSABI_MSK) + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_ARC_ATTRIBUTES (SHT_LOPROC + 1) /* ARC attributes section. */ /* ARCompact/ARCv2 specific relocs. */ #define R_ARC_NONE 0x0 @@ -4166,7 +4222,7 @@ enum #define R_ARC_16 0x2 #define R_ARC_24 0x3 #define R_ARC_32 0x4 -#define R_ARC_B26 0x5 + #define R_ARC_B22_PCREL 0x6 #define R_ARC_H30 0x7 #define R_ARC_N8 0x8 @@ -4206,16 +4262,23 @@ enum #define R_ARC_SECTOFF_ME_2 0x2A #define R_ARC_SECTOFF_1 0x2B #define R_ARC_SECTOFF_2 0x2C +#define R_ARC_SDA_12 0x2D +#define R_ARC_SDA16_ST2 0x30 +#define R_ARC_32_PCREL 0x31 #define R_ARC_PC32 0x32 #define R_ARC_GOTPC32 0x33 #define R_ARC_PLT32 0x34 #define R_ARC_COPY 0x35 #define R_ARC_GLOB_DAT 0x36 -#define R_ARC_JUMP_SLOT 0x37 +#define R_ARC_JMP_SLOT 0x37 #define R_ARC_RELATIVE 0x38 #define R_ARC_GOTOFF 0x39 #define R_ARC_GOTPC 0x3A #define R_ARC_GOT32 0x3B +#define R_ARC_S21W_PCREL_PLT 0x3C +#define R_ARC_S25H_PCREL_PLT 0x3D + +#define R_ARC_JLI_SECTOFF 0x3F #define R_ARC_TLS_DTPMOD 0x42 #define R_ARC_TLS_DTPOFF 0x43 @@ -4224,9 +4287,12 @@ enum #define R_ARC_TLS_GD_LD 0x46 #define R_ARC_TLS_GD_CALL 0x47 #define R_ARC_TLS_IE_GOT 0x48 -#define R_ARC_TLS_DTPOFF_S9 0x4a -#define R_ARC_TLS_LE_S9 0x4a -#define R_ARC_TLS_LE_32 0x4b +#define R_ARC_TLS_DTPOFF_S9 0x49 +#define R_ARC_TLS_LE_S9 0x4A +#define R_ARC_TLS_LE_32 0x4B +#define R_ARC_S25W_PCREL_PLT 0x4C +#define R_ARC_S21H_PCREL_PLT 0x4D +#define R_ARC_NPS_CMEM16 0x4E /* OpenRISC 1000 specific relocs. */ #define R_OR1K_NONE 0 diff --git a/tests/invalid-elf.sh b/tests/invalid-elf.sh index c124501d..40e86577 100755 --- a/tests/invalid-elf.sh +++ b/tests/invalid-elf.sh @@ -1,4 +1,4 @@ -#! /bin/sh -u +#! /bin/sh -ue # Usage: killed_by_signal $? # @@ -18,6 +18,24 @@ TEST_DIR=$(dirname "$(readlink -f "$0")")/invalid-elf TEST_CASES="invalid-shrstrtab-idx invalid-shrstrtab-size invalid-shrstrtab-zero invalid-shrstrtab-nonterm invalid-shdr-name invalid-phdr-offset" +# Issue #64 regression test. Test ELF provided by issue submitter. +TEST_CASES=$TEST_CASES' invalid-phdr-issue-64' + +# shellcheck disable=SC2034 +invalid_shrstrtab_idx_MSG='data region extends past file end' +# shellcheck disable=SC2034 +invalid_shrstrtab_size_MSG='data region extends past file end' +# shellcheck disable=SC2034 +invalid_shrstrtab_zero_MSG='data region extends past file end' +# shellcheck disable=SC2034 +invalid_shrstrtab_nonterm_MSG='data region extends past file end' +# shellcheck disable=SC2034 +invalid_shdr_name_MSG='data region extends past file end' +# shellcheck disable=SC2034 +invalid_phdr_offset_MSG='program header table out of bounds' +# shellcheck disable=SC2034 +invalid_phdr_issue_64_MSG='program header table out of bounds' + FAILED_TESTS="" for tcase in $TEST_CASES; do @@ -26,10 +44,16 @@ for tcase in $TEST_CASES; do exit 1 fi - ../src/patchelf --output /dev/null "$TEST_DIR/$tcase" - if killed_by_signal $?; then + ../src/patchelf --output /dev/null "$TEST_DIR/$tcase" && res=$? || res=$? + if killed_by_signal "$res"; then FAILED_TESTS="$FAILED_TESTS $tcase" fi + + var=$(echo "$tcase-MSG" | tr '-' '_') + msg= + eval "msg=\${$var}" + ../src/patchelf --output /dev/null "$TEST_DIR/$tcase" 2>&1 | + grep "$msg" >/dev/null 2>/dev/null done if [ -z "$FAILED_TESTS" ]; then diff --git a/tests/invalid-elf/invalid-phdr-issue-64 b/tests/invalid-elf/invalid-phdr-issue-64 new file mode 100644 index 00000000..ca49e0ac Binary files /dev/null and b/tests/invalid-elf/invalid-phdr-issue-64 differ diff --git a/tests/repeated-updates.sh b/tests/repeated-updates.sh index 669b11d5..da7715ab 100755 --- a/tests/repeated-updates.sh +++ b/tests/repeated-updates.sh @@ -2,6 +2,7 @@ SCRATCH=scratch/$(basename "$0" .sh) PATCHELF=$(readlink -f "../src/patchelf") +READELF=${READELF:-readelf} rm -rf "${SCRATCH}" mkdir -p "${SCRATCH}" @@ -18,7 +19,7 @@ ${PATCHELF} --add-needed ./libbar.so simple # Test that repeatedly modifying a string inside a shared library does not # corrupt it due to the addition of multiple PT_LOAD entries ############################################################################### -load_segments_before=$(readelf -W -l libbar.so | grep -c LOAD) +load_segments_before=$(${READELF} -W -l libbar.so | grep -c LOAD) for _ in $(seq 1 100) do @@ -27,7 +28,7 @@ do ./simple || exit 1 done -load_segments_after=$(readelf -W -l libbar.so | grep -c LOAD) +load_segments_after=$(${READELF} -W -l libbar.so | grep -c LOAD) ############################################################################### # To be even more strict, check that we don't add too many extra LOAD entries diff --git a/tests/shared-rpath.sh b/tests/shared-rpath.sh index 8e6e26f3..1fa46b9d 100755 --- a/tests/shared-rpath.sh +++ b/tests/shared-rpath.sh @@ -2,7 +2,8 @@ PATCHELF=$(readlink -f "../src/patchelf") SCRATCH="scratch/$(basename "$0" .sh)" -READELF=${READELF:-readelf} +NM=${NM:-nm} +STRINGS=${STRINGS:-strings} LIB_NAME="${PWD}/libshared-rpath.so" @@ -11,11 +12,11 @@ mkdir -p "${SCRATCH}" cd "${SCRATCH}" has_x() { - strings "$1" | grep -c "XXXXXXXX" + ${STRINGS} "$1" | grep -c "XXXXXXXX" } -nm -D "${LIB_NAME}" | grep a_symbol_name -previous_cnt="$(strings "${LIB_NAME}" | grep -c a_symbol_name)" +${NM} -D "${LIB_NAME}" | grep a_symbol_name +previous_cnt="$(${STRINGS} "${LIB_NAME}" | grep -c a_symbol_name)" echo "#### Number of a_symbol_name strings in the library: $previous_cnt" @@ -25,12 +26,12 @@ echo "#### Rename the rpath to something larger than the original" "${PATCHELF}" --set-rpath a_very_big_rpath_that_is_larger_than_original --output liblarge-rpath.so "${LIB_NAME}" echo "#### Checking symbol is still there" -nm -D liblarge-rpath.so | grep a_symbol_name +${NM} -D liblarge-rpath.so | grep a_symbol_name echo "#### Checking there are no Xs" [ "$(has_x liblarge-rpath.so)" -eq 0 ] || exit 1 -current_cnt="$(strings liblarge-rpath.so | grep -c a_symbol_name)" +current_cnt="$(${STRINGS} liblarge-rpath.so | grep -c a_symbol_name)" echo "#### Number of a_symbol_name strings in the modified library: $current_cnt" [ "$current_cnt" -eq "$previous_cnt" ] || exit 1 @@ -40,10 +41,10 @@ echo "#### Rename the rpath to something shorter than the original" "${PATCHELF}" --set-rpath shrt_rpth --output libshort-rpath.so "${LIB_NAME}" echo "#### Checking symbol is still there" -nm -D libshort-rpath.so | grep a_symbol_name +${NM} -D libshort-rpath.so | grep a_symbol_name echo "#### Number of a_symbol_name strings in the modified library: $current_cnt" -current_cnt="$(strings libshort-rpath.so | grep -c a_symbol_name)" +current_cnt="$(${STRINGS} libshort-rpath.so | grep -c a_symbol_name)" [ "$current_cnt" -eq "$previous_cnt" ] || exit 1 echo "#### Now liblarge-rpath.so should have its own rpath, so it should be allowed to taint it"