Commit Graph

501 Commits

Author SHA1 Message Date
Harmen Stoppels
1b4890a658 Bump version and update release notes
fixes https://github.com/NixOS/patchelf/pull/338
2021-11-27 18:48:23 +01:00
Jörg Thalheim
411e004f48 fix setting empty rpath 2021-11-27 16:53:30 +01:00
Jörg Thalheim
31e9c719d4 use memcpy instead of strcpy to set rpath
Since we already no the size, this is faster.
2021-11-27 16:53:30 +01:00
Michal Sojka
3f5fff20c5 Don't try to parse .dynamic section of type NOBITS
Otherwise, patchelf segfaults when it encounters DT_NEEDED in the read
garbage. Corresponding backtrace is:

    #0  0x00007ffff7c275f7 in __strlen_avx2 () from /nix/store/cvr0kjg2q7z2wwhjblx6c73rv422k8cm-glibc-2.33-47/lib/libc.so.6
    #1  0x00007ffff7f2d448 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /nix/store/lg104nh0szci8slz5z6494m457jm5y3p-gcc-10.3.0-lib/lib/libstdc++.so.6
    #2  0x000000000040fe0f in ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, unsigned short>::modifyRPath (this=0x7fffffffbaa0,
        op=ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, unsigned short>::rpPrint, allowedRpathPrefixes=std::vector of length 0, capacity 0, newRPath="") at patchelf.cc:1351
    #3  0x00000000004061c3 in patchElf2<ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, unsigned short> > (elfFile=..., fileContents=std::shared_ptr<std::vector<unsigned char, std::allocator<unsigned char> >> (use count 3, weak count 0) = {...},
        fileName="libsystemd.debug") at patchelf.cc:1805
    #4  0x0000000000404774 in patchElf () at patchelf.cc:1848
    #5  0x000000000040551c in mainWrapped (argc=3, argv=0x7fffffffc148) at patchelf.cc:2003
    #6  0x0000000000405913 in main (argc=3, argv=0x7fffffffc148) at patchelf.cc:2011

NOBIT sections are included in the section headers table but occupy no
actual space in the file. .dynamic sections of this types are created,
for example, by `strip --only-keep-debug`.

I'm not sure whether calling error() would be more appropriate than
ignoring this situation with debug/return. I chose ignoring it,
because error() caused autoPatchelfHook to fail with my package. Also
the rest of modifyRPath method simply calls debug/return in similar
situations.
2021-11-27 16:53:30 +01:00
Jörg Thalheim
2a540f020a fix use-after-free in normalizeNoteSegments 2021-11-27 16:53:30 +01:00
Jörg Thalheim
35a5b93299 correct EINTR handling in writeFile 2021-11-27 16:53:30 +01:00
Ivan A. Melnikov
89ae3e2614 Adjust PT_MIPS_ABIFLAGS segment if present
When loading the executable on MIPS, the dynamic loader looks for MIPS
ABI flags using PT_MIPS_ABIFLAGS header. The flags themselves are stored
in the .MIPS.abiflags section, so the header must be updated when the
section is moved.

Here we also import PT_MIPS_ABIFLAGS definition from glibc commit
0bd956720c457ff054325b48f26ac7c91cb060e8.

Closes: #82
Signed-off-by: Ivan A. Melnikov <iv@altlinux.org>
2021-11-27 16:53:30 +01:00
Ivan A. Melnikov
f72f98e6ca Adjust DT_MIPS_RLD_MAP_REL dynamic section entry if present
`patchelf --set-rpath` corrupted executables on mips32el: the dynamic
liker crushed with Segmentation fault when loading any executable with
RPATH added that way.

The problem was around the MIPS-specific mechanism of setting up the
debug map pointer. When DT_MIPS_RLD_MAP_REL entry in the dynamic section
is present, it holds the relative address of __RLD_MAP -- an offset
relative to this dynamic section entry. Dynamic linker puts the
pointer to the `r_debug` structure there.

When patchelf updates the executable RPATH, it moves the .dynamic
section both in the binary and in memory, while __RLD_MAP is not moved
in memory, since it belongs to special .rld_map section that has type
PROGBITS. So, the offset stored in DT_MIPS_RLD_MAP_REL entry is not
valid anymore and should be updated.

This commit adds the necessary update.

In the corner case when DT_MIPS_RLD_MAP_REL is present, but
.rld_map section is not, the dynamic loader writes the debug
pointer to some arbitrary bytes in memory. To avoid crushes
on otherwise "working" binaries, we set offset to zero
so that the dynamic loader would just overwrite the dynamic
section.

Here we also import DT_MIPS_RLD_MAP_REL definition in elf.h form
glibc commit a2057c984e4314c3740f04cf54e36c824e4c8f32.

Refs: #82
Signed-off-by: Ivan A. Melnikov <iv@altlinux.org>
2021-11-27 16:53:30 +01:00
Jörg Thalheim
6f3b35d716 fix binaries without .gnu.hash section 2021-11-27 16:13:00 +01:00
Eelco Dolstra
a949ff2331 Bump version 0.13 2021-08-05 14:39:43 +02:00
Domen Kožar
dab44118d7 Merge pull request #246 from xavierabellan/add-rpath
Added option --add-rpath
2021-08-05 12:10:59 +02:00
Domen Kožar
4ee62cbd52 Merge pull request #269 from telent/endianness-fix-for-shrink-rpath
convert endian when checking library machine type
2021-08-05 12:03:48 +02:00
Domen Kožar
4e1b46a334 fix tests DIST 2021-08-05 12:03:39 +02:00
Domen Kožar
a71fa6b341 Merge pull request #290 from ius/endianness-fix
tests: add e_machine endianness test (#269)
2021-08-05 11:56:04 +02:00
Domen Kožar
f823fa3143 Merge branch 'master' into endianness-fix 2021-08-05 11:55:53 +02:00
Domen Kožar
add92c1fe7 Merge pull request #235 from emlix/cleanups
minor improvements
2021-08-04 15:45:27 +02:00
Domen Kožar
1e1544a8ab Merge pull request #293 from ovpanait/master
[v2] tests: add testcase for alignment issues with contiguous note sections
2021-08-04 15:43:17 +02:00
Domen Kožar
9592fdf3a1 Merge pull request #275 from rpurdie/master
patchelf: Fix alignment issues with contiguous note sections
2021-08-04 15:43:07 +02:00
Ovidiu Panait
d2bb23badf tests: add testcase for alignment issues with contiguous note sections
Add a testcase for the following reported alignment issue with contiguous note
sections (#275):

"""
If a binary has multiple SHT_NOTE sections and corresponding PT_NOTE
headers, we can see the error:

patchelf: cannot normalize PT_NOTE segment: non-contiguous SHT_NOTE sections

if the SHT_NOTE sections aren't sized to end on aligned boundaries. An example
would be a binary with:

[ 2] .note.ABI-tag NOTE 00000000000002f4 000002f4
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.propert NOTE 0000000000000318 00000318
0000000000000030 0000000000000000 A 0 0 8
[ 4] .note.gnu.build-i NOTE 0000000000000348 00000348
0000000000000024 0000000000000000 A 0 0 4

NOTE 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x0000000000000030 0x0000000000000030 R 0x8
NOTE 0x00000000000002f4 0x00000000000002f4 0x00000000000002f4
0x0000000000000078 0x0000000000000074 R 0x4

since the PT_NOTE section at 2f4 covers [2] and [3] but the code
calclates curr_off should be 314, not the 318 in the binary. This
is an alignment issue.
"""

Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
2021-08-04 12:31:15 +03:00
Domen Kožar
4d03718b17 Revert "tests: add testcase for alignment issues with contiguous note sections"
This reverts commit fccd901efe.
2021-08-03 16:30:13 +02:00
Domen Kožar
b6c73c4c93 Run tests by default 2021-08-03 16:24:33 +02:00
Domen Kožar
83fac7e0ce Merge pull request #289 from ovpanait/master
tests: add testcase for alignment issues with contiguous note sections
2021-08-03 15:53:42 +02:00
Domen Kožar
8889455e54 Merge pull request #292 from ovpanait/issue-291
addNeeded: fix assertion triggered due to bad .dynstr section resize
2021-08-03 14:54:37 +02:00
Ovidiu Panait
3300999317 tests: plain-needed.sh: add tescases for --add-needed-/--remove-needed
Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
2021-07-24 19:25:16 +03:00
Ovidiu Panait
f533f7b898 addNeeded: fix assertion triggered due to bad .dynstr section resize
When running "--add-needed" subcommand on a hello world binary, the
following assertion is triggered:
"""
$ echo "int main() {}" | gcc -xc -o test -
$ patchelf --add-needed foo.so --output /dev/null test
patching ELF file 'scratch/plain-needed/main'
patchelf: patchelf.cc:1167: void setSubstr(std::string&, unsigned int, const string&): Assertion `pos + t.size() <= s.size()' failed.
Aborted (core dumped)
"""

This is due to the fact that .dynstr section is resized incorrectly:
"""
    unsigned int length = std::count_if(libs.begin(), libs.end(),
        [](const std::string & lib) { return lib.size() + 1; });
"""

std::count_if() will return the number of strings in std::set<std::string> libs
(e.g. 1 in the foo.so example). However, in order to properly resize the
.dynstr section, subsequent code expects the size (in bytes) of all the strings
that are to be appended:
"""
    std::string & newDynStr = replaceSection(".dynstr",
        rdi(shdrDynStr.sh_size) + length + 1);
"""

To fix this, iterate over "libs" and compute the length of all the strings that
need to be added to the .dynstr section.

Fixes #291.

Fixes: fce77b7cd8 ("replace for loop with any_of")
Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
2021-07-24 19:25:16 +03:00
Joerie de Gram
4052850d22 tests: add e_machine endianness test (#269) 2021-07-24 01:32:37 +02:00
Ovidiu Panait
fccd901efe tests: add testcase for alignment issues with contiguous note sections
Add a testcase for the following reported alignment issue with contiguous note
sections (#275):

"""
If a binary has multiple SHT_NOTE sections and corresponding PT_NOTE
headers, we can see the error:

patchelf: cannot normalize PT_NOTE segment: non-contiguous SHT_NOTE sections

if the SHT_NOTE sections aren't sized to end on aligned boundaries. An example
would be a binary with:

[ 2] .note.ABI-tag NOTE 00000000000002f4 000002f4
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.propert NOTE 0000000000000318 00000318
0000000000000030 0000000000000000 A 0 0 8
[ 4] .note.gnu.build-i NOTE 0000000000000348 00000348
0000000000000024 0000000000000000 A 0 0 4

NOTE 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x0000000000000030 0x0000000000000030 R 0x8
NOTE 0x00000000000002f4 0x00000000000002f4 0x00000000000002f4
0x0000000000000078 0x0000000000000074 R 0x4

since the PT_NOTE section at 2f4 covers [2] and [3] but the code
calclates curr_off should be 314, not the 318 in the binary. This
is an alignment issue.
"""

Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
2021-07-21 22:41:36 +03:00
Domen Kožar
7ec8edbe09 Merge pull request #282 from iv-m/endianness-fix
rewriteSectionsLibrary: Fix endianness issue
2021-06-21 13:24:15 +02:00
Ivan A. Melnikov
83eab25c30 rewriteSectionsLibrary: Fix endianness issue
Currently, patchelf creats a broken PPC binary in
tests/no-rpath-pie-powerpc.sh:

$ readelf -l scratch/no-rpath-pie-powerpc/no-rpath
[...]
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x34000000 0x34000000 0x00120 0x00120 R   0x4
[...]

That happens because 4efbce41 lost endianness conversion
for rewriteSectionsLibrary. This commit puts it back.

Fixes: 4efbce410d
2021-06-21 12:29:30 +04:00
Domen Kožar
251b98cac8 Merge pull request #281 from iv-m/fix-PT_PHDR
Fix updating program header table segment
2021-06-19 15:36:02 +02:00
Domen Kožar
d1e567e3bf Merge pull request #278 from satmandu/PR243
Added test file for PR243, rebased off of PR270 & PR243
2021-06-19 15:35:40 +02:00
Ivan A. Melnikov
699f41632a Fix updating program header table segment
Without '&', the code updates temporary and thus
does essentially nothing. But updating PT_PHDR
segment is required for many architectures.

Fixes: dd4d2af8db
2021-06-16 17:44:09 +04:00
Satadru Pramanik
f276b58ebb Change to 'for (auto & phdr : phdrs) { .' as used elsewhere 2021-05-27 23:06:58 -04:00
Satadru Pramanik
8f94e116f3 add PR243 reproducer 2021-05-20 17:10:38 -04:00
Satadru Pramanik
4efbce410d merge from PR243 2021-05-20 16:52:21 -04:00
Satadru Pramanik
d75ad358f4 Add testfile from PR270 2021-05-20 13:40:54 -04:00
Richard Purdie
2d0e0b9218 patchelf: Fix alignment issues with contiguous note sections
If a binary has multiple SHT_NOTE sections and corresponding PT_NOTE
headers, we can see the error:

patchelf: cannot normalize PT_NOTE segment: non-contiguous SHT_NOTE sections

if the SHT_NOTE sections aren't sized to end on aligned boundaries. An example
would be a binary with:

  [ 2] .note.ABI-tag     NOTE             00000000000002f4  000002f4
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.propert NOTE             0000000000000318  00000318
       0000000000000030  0000000000000000   A       0     0     8
  [ 4] .note.gnu.build-i NOTE             0000000000000348  00000348
       0000000000000024  0000000000000000   A       0     0     4

  NOTE           0x0000000000000318 0x0000000000000318 0x0000000000000318
                 0x0000000000000030 0x0000000000000030  R      0x8
  NOTE           0x00000000000002f4 0x00000000000002f4 0x00000000000002f4
                 0x0000000000000078 0x0000000000000074  R      0x4

since the PT_NOTE section at 2f4 covers [2] and [3] but the code
calclates curr_off should be 314, not the 318 in the binary. This
is an alignment issue.

To fix this, we need to round curr_off to the next section alignment.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2021-05-02 13:06:31 +01:00
MatrixLing
ff6f21fad5 fixed phdr bug 2021-04-12 09:25:35 +08:00
Daniel Barlow
013ce840ab convert endian when checking library machine type 2021-03-31 22:27:40 +01:00
Rolf Eike Beer
acb4665c17 avoid needless copies of std::string 2021-03-16 08:28:10 +01:00
Rolf Eike Beer
554dec3668 do not add new string entries when changing libraries to themself 2021-03-16 08:26:28 +01:00
Rolf Eike Beer
4967cdcd0e fix -Wshadow warnings 2021-03-16 08:26:27 +01:00
Rolf Eike Beer
0fcf278953 silence compiler warning because of different signedness
../../patchelf/src/patchelf.cc:835:19: warning: comparison of integer expressions of different signedness: 'long long unsigned int' and 'off_t' {aka 'long long int'} [-Wsign-compare]
  835 |     assert(curOff == startOffset + neededSpace);
      |            ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
2021-03-16 08:24:20 +01:00
Rolf Eike Beer
40640a9c11 add new SHF_* flags from binutils 2021-03-16 08:24:20 +01:00
Rolf Eike Beer
a935c61e74 only one section name can match 2021-03-16 08:23:32 +01:00
Rolf Eike Beer
d628ab9378 avoid needless memory allocation when replacing sections 2021-03-16 08:23:09 +01:00
Eelco Dolstra
f376fe61ba Merge pull request #266 from neheb/int
fix wrong cast
2021-02-26 15:50:04 +01:00
Rosen Penev
1af4453428 fix wrong cast
The original code which worked was size_t(A + B * C). size_t(A + B)
breaks it. A + size_t(B * C) is correct.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-02-25 15:01:21 -08:00
Eelco Dolstra
0ad9548c02 Style fixes 2021-02-15 13:12:02 +01:00
Eelco Dolstra
8268756636 Merge pull request #262 from neheb/man
clang-tidy fixes
2021-02-15 13:08:08 +01:00