Skip to content
This repository has been archived by the owner on Mar 12, 2019. It is now read-only.

patchelf: Fails on static executables: cannot find section .interp #4

Closed
sjackman opened this issue Apr 29, 2016 · 19 comments
Closed
Assignees
Labels

Comments

@sjackman
Copy link
Member

From @sjackman on March 29, 2016 22:53

https://travis-ci.org/Linuxbrew/linuxbrew/builds/119350327#L2890

/home/travis/build/Linuxbrew/linuxbrew/Cellar/patchelf/0.9/bin/patchelf --set-rpath @@HOMEBREW_PREFIX@@/lib --set-interpreter /lib64/ld-linux-x86-64.so.2 /home/travis/build/Linuxbrew/linuxbrew/Cellar/afl-fuzz/2.09b/share/afl/testcases/others/elf/small_exec.elf 
cannot find section .interp
Error: undefined method `write' for nil:NilClass

Copied from original issue: Linuxbrew/legacy-linuxbrew#1005

@sjackman
Copy link
Member Author

That's the error message that patchelf gives when it attempts to relocate a static executable. This bug definitely needs to be fixed. It could be fixed in patchelf to make this a warning rather than an error. That's probably the simpler fix. The alternative is that Linuxbrew could check whether the ELF is dynamic or static, and skip patchelf for static executables. The problem here is that I haven't found an easy way to distinguish dynamic from dynamic. The easiest way would be to call out to file.

@DoomHammer
Copy link
Contributor

There was a similar problem with Alpine binaries IIRC. Has this been fixed somehow?

@sjackman
Copy link
Member Author

No, it has not been fixed. The possible solutions are:

  1. Fix patchelf to make the above error a warning rather than an error
  2. Use file to skip static executables
  3. Use ruby-elf gem to skip static executables

I'm inclined for solution 1. Your thoughts?

@sjackman
Copy link
Member Author

I was avoiding file because it's an external dependency that may not be available. ruby-elf would have to vendored in.

@rwhogg
Copy link
Contributor

rwhogg commented Apr 29, 2016

Counting on file means we either a) depend on it being available or b) drag in a dependency on homebrew/dupes/file-formula. 3 is probably better than 2, if only for language consistency.

@sjackman, are you still experiencing this issue? If so, then it sounds like we might be best off skipping static executables.

@sjackman
Copy link
Member Author

sjackman commented Apr 29, 2016

Yep, this issue is current, and we need to skip static executables. How though? Fix patchelf or pull in ruby-elf?

@rwhogg
Copy link
Contributor

rwhogg commented Apr 29, 2016

Sorry, I wasn't clear. By that, I meant we probably shouldn't be modifying patchelf. Rather, we should ensure that any static executable doesn't get that far, which would imply option 2 or 3.

I'm more inclined to use patchelf to handle dynamic executables and treat passing static executables to it as undefined behaviour.

Strictly my opinion, I emphasize. Maybe we should defer to the NixOS developers on what they do about static executables?

@sjackman
Copy link
Member Author

I didn't click on the link. My fault. I haven't experienced patchelf segfaulting recently as in NixOS/patchelf#78. This issue may be fixed. I think we get the above error message now. I just thought of a really simple fix. If patchelf fails, check the error message. If it's exactly cannot find section .interp, we disregard the error. Sound good?

I've asked the NixOS developers in NixOS/patchelf#78 if they would consider adding an option to make the above error a warning rather than an error.

@sjackman
Copy link
Member Author

sjackman commented Jun 2, 2016

@DoomHammer Piotr, do you have a fix for patchelf failing on static executables?

@DoomHammer
Copy link
Contributor

@sjackman
Copy link
Member Author

sjackman commented Jun 3, 2016

I believe #352 fixes the error cannot find section, which affects Go executables, but I don't believe it fixes cannot find section .interp, which affects static executables. Can you confirm?

@DoomHammer
Copy link
Contributor

You are right, this was a different issue. ruby-elf might be the way to go, but consider that file is already being used and causing silent failures when unavailable (Debian Sid casus). Fixing this upstream should be the priority, I think?

@sjackman
Copy link
Member Author

Now that file is an upstream dependency of Homebrew (it wasn't before) to determine whether a file is a text file or a binary file, should we also use file to determine if an ELF executable is dynamic or static? I don't really see a downside. file is effectively already a dependency of Linuxbrew now.

@DoomHammer
Copy link
Contributor

Agreed, resources such as file shouldn't go to waste ;)

@sjackman
Copy link
Member Author

sjackman commented Jun 15, 2016

Great. Agreed. That should fix the cannot find section .interp and cannot find section .dynamic issues. Would you like to take a stab at using file to avoid using patchelf on static ELF files?

@sjackman
Copy link
Member Author

Compiling on a CentOS 5 machine, I ran

brew install --build-bottle --with-static --cc=gcc-4.4 patchelf
brew bottle --rb patchelf

It would be nice to find a recipe that we can run on Ubuntu 14 that builds a working bottle for CentOS 5.

@DoomHammer DoomHammer self-assigned this Jun 17, 2016
@DoomHammer
Copy link
Contributor

I'll take it.

@sjackman
Copy link
Member Author

Found a recipe for building on Ubuntu 14:

  1. install glibc
  2. remove patchelf
  3. install patchelf --with-static
  4. bottle patchelf

@sjackman
Copy link
Member Author

PR #75 uses file to test whether an executable is static and skips relocating the executable with patchelf if so.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants