diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-05-01 17:32:28 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-05-02 13:06:31 +0100 |
commit | 2d0e0b92184d0ca7eb70e824f2c17cc09703f9e9 (patch) | |
tree | 74af1ad906ba3f1ad73f385539200849da337a30 | |
parent | f376fe61bae57e9e50f4622f5a44febb4f5bfd3c (diff) | |
download | patchelf-2d0e0b92184d0ca7eb70e824f2c17cc09703f9e9.tar.gz |
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>
-rw-r--r-- | src/patchelf.cc | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc index 287fea8..b0b0ef3 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -1000,8 +1000,9 @@ void ElfFile<ElfFileParamNames>::normalizeNoteSegments() size_t size = 0; for (const auto & shdr : shdrs) { if (rdi(shdr.sh_type) != SHT_NOTE) continue; - if (rdi(shdr.sh_offset) != curr_off) continue; + if (rdi(shdr.sh_offset) != roundUp(curr_off, rdi(shdr.sh_addralign))) continue; size = rdi(shdr.sh_size); + curr_off = roundUp(curr_off, rdi(shdr.sh_addralign)); break; } if (size == 0) |