Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG FIX] false alarm for non overlapping sections #230

Merged
merged 1 commit into from Nov 19, 2020

Conversation

rmNULL
Copy link
Contributor

@rmNULL rmNULL commented Aug 18, 2020

What these changes do

avoids recheck of marked note segments already synced with note sections,

This also serves as a bug fix when a previously synced note segment
overlaps with another section.

Steps to reproduce the bug

pushd /tmp

wget -O util-linux.bottle.tar.gz "https://bintray.com/linuxbrew/bottles/download_file?file_path=util-linux-2.36.x86_64_linux.bottle.tar.gz"
tar -zxf util-linux.bottle.tar.gz
chmod +w util-linux/2.36/bin/chmem
patchelf --force-rpath --set-rpath "ngcfpqardtudtlvqujdskyvgehsyxyxawbqchomweuxfbvfrfekhgnrtlsftwwjcpvoyedaoaikgkgyxmodpkafkcubibuiasuabbziihwijnfjnsqpqmlcwzxzxvphnclpqezyjrtetcmomldsh" /tmp/util-linux/2.36/bin/chmem

Description of bug

Running the above described commands fails with

patchelf: unsupported overlap of SHT_NOTE and PT_NOTE

why is this happening ?

patchelf/src/patchelf.cc

Lines 725 to 741 in 7aa6b90

Elf_Off p_start = rdi(phdrs[j].p_offset);
Elf_Off p_end = p_start + rdi(phdrs[j].p_filesz);
Elf_Off s_start = rdi(orig_shdr.sh_offset);
Elf_Off s_end = s_start + rdi(orig_shdr.sh_size);
/* Skip if no overlap. */
if (!(s_start >= p_start && s_start < p_end) &&
!(s_end > p_start && s_end <= p_end))
continue;
/* We only support exact matches. */
if (p_start != s_start || p_end != s_end)
error("unsupported overlap of SHT_NOTE and PT_NOTE");
phdrs[j].p_offset = shdr.sh_offset;
phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr;
phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size;

In the above link, the previously updated program header will be compared against un updated section header(orig_shdr)

verbose explanation

i'll paste the PATCHELF_DEBUG=1 log here,
if the log makes sense, please skip the writing.

patching ELF file '/tmp/util-linux/2.36/bin/chmem'
new rpath is 'ngcfpqardtudtlvqujdskyvgehsyxyxawbqchomweuxfbvfrfekhgnrtlsftwwjcpvoyedaoaikgkgyxmodpkafkcubibuiasuabbziihwijnfjnsqpqmlcwzxzxvphnclpqezyjrtetcmomldsh'
rpath is too long, resizing...
replacing section '.dynstr' with size 1365
this is an executable
using replaced section '.dynstr'
last replaced is 6
looking at section '.interp'
replacing section '.interp' which is in the way
looking at section '.note.ABI-tag'
replacing section '.note.ABI-tag' which is in the way
looking at section '.note.gnu.build-id'
replacing section '.note.gnu.build-id' which is in the way
looking at section '.gnu.hash'
replacing section '.gnu.hash' which is in the way
looking at section '.dynsym'
replacing section '.dynsym' which is in the way
looking at section '.dynstr'
first reserved offset/addr is 0x11b0/0x4011b0
first page is 0x400000
needed space is 4728
needed space is 4784
needed pages is 1
changing alignment of program header 2 from 2097152 to 4096
changing alignment of program header 6 from 2097152 to 4096
clearing first 7944 bytes
rewriting section '.dynstr' from offset 0x1cf0 (size 1216) to offset 0x2a8 (size 1365)
rewriting section '.dynsym' from offset 0x12e8 (size 2568) to offset 0x800 (size 2568)
rewriting section '.gnu.hash' from offset 0x12a8 (size 64) to offset 0x1208 (size 64)
rewriting section '.interp' from offset 0x1238 (size 30) to offset 0x1248 (size 30)
rewriting section '.note.ABI-tag' from offset 0x1260 (size 32) to offset 0x1268 (size 32)
rewriting section '.note.gnu.build-id' from offset 0x1280 (size 36) to offset 0x1288 (size 36)
patchelf: unsupported overlap of SHT_NOTE and PT_NOTE

orig_shdr = .note.ABI-tag is at 0x1260
it finds a matching segment from 0x1260 to 0x1280
and updates the phdr values to new shdr values
which is 0x1268 .. 0x1288

for the next replaced_section
orig_shdr = .note.gnu.build-id is at 0x1280
it checks for overlap between 0x1280 .. 0x12a4
the previously updated phdr( 0x1268 .. 0x1288)
overlaps with this section.

phew 😥

Another point being,
it doesn't make sense to check the program once mapped to section
as the whole point of normalize note sections is to create 1 - 1 mapping
between section and segments.

Alternative ways to resolve the issue are welcome.
Thanks

Copy link

@sjackman sjackman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested aesthetic improvements. Looks good!

src/patchelf.cc Show resolved Hide resolved
src/patchelf.cc Show resolved Hide resolved
src/patchelf.cc Show resolved Hide resolved
@domenkozar
Copy link
Member

Would be great to add a regression test.

@rmNULL
Copy link
Contributor Author

rmNULL commented Aug 21, 2020

@domenkozar
sorry im new here, i see the commit(https://github.com/NixOS/patchelf/blob/master/tests/build-id.sh) as "regression test",
will a test in similar nature do ?

@domenkozar
Copy link
Member

@rmNULL exactly!

…e sections to segments.

This also serves as a bug fix when a previously synced note segment
overlaps with another section and creates a false alarm.
@rmNULL rmNULL force-pushed the fix-wrong-unsupported-overlap branch 2 times, most recently from 15c9d7e to 6edec83 Compare August 25, 2020 22:29
@aaronjanse
Copy link
Member

I think I just ran into this while packaging Energia (https://energia.nu)

https://gist.github.com/aaronjanse/fa6d76c57c5e07c49dfe6094e4dd7de8

@sjackman
Copy link

@delroth @Mic92 @edolstra Are you able to give this PR a review? It's a blocker for Homebrew on Linux.

sjackman added a commit to sjackman/homebrew-core that referenced this pull request Nov 18, 2020
BrewTestBot pushed a commit to Homebrew/homebrew-core that referenced this pull request Nov 18, 2020
See NixOS/patchelf#230

Closes #65137.

Signed-off-by: Michka Popoff <3406519+iMichka@users.noreply.github.com>
@Mic92
Copy link
Member

Mic92 commented Nov 19, 2020

@sjackman I cannot merge PRs here, but I know from experience that bug fixes with tests get merged faster, i.e. #251

@edolstra edolstra merged commit 81a48fd into NixOS:master Nov 19, 2020
@sjackman
Copy link

Thank you for merging, Eelco! 🌟

@sjackman
Copy link

and thank you for the fix, @rmNULL! 🏆

Yarny0 added a commit to Yarny0/nixpkgs that referenced this pull request Dec 10, 2020
Starting with version 0.12, patchelf sometimes returns
an error complaining about overlapping sections:

> unsupported overlap of SHT_NOTE and PT_NOTE

This issue was reported for tsm-client:

NixOS#106257

There is a patch available in this pull request:

NixOS/patchelf#230

This patch fixes tsm-client, maybe other packages as well.

This commit adds the patch to the nixpkgs patchelf build recipe.

Note that the patch may also be downloaded directly here:

https://github.com/NixOS/patchelf/pull/230.patch

However, in contrast to common nixpkgs policy,
the patch is not fetched with fetchpatch,
but is copied directly into nixpkgs tree.
This is necessary because patchelf
is a dependency of fetchpatch.
See also the note at the top of the patchelf build recipe
in pkgs/development/tools/misc/patchelf/default.nix .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants