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

packaging: use local patchelf #2519

Merged
merged 13 commits into from
Apr 8, 2019

Conversation

cmatsuoka
Copy link
Contributor

Pull patchelf from the latest stable tag from the upstream repository,
which contains patches critical for snapcraft to work properly with
Go ELF binaries.

Noteworthy patches and issues fixed:

LP: #1805205

Signed-off-by: Claudio Matsuoka claudio.matsuoka@canonical.com

  • Have you followed the guidelines for contributing?
  • Have you signed the CLA?
  • Have you successfully run ./runtests.sh static?
  • Have you successfully run ./runtests.sh tests/unit?

Pull patchelf from the latest stable tag from the upstream repository,
which contains patches critical for snapcraft to work properly with
Go ELF binaries.

Noteworthy patches and issues fixed:

- Avoid inflating file sizes needlessly and allow binaries to be stripped
- patchelf --set-interpreter fails with `cannot find section` (canonical#66)
- --set-interpreter gives "cannot find section" for go binary (canonical#138)

LP: #1805205

Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
Copy link
Collaborator

@sergiusens sergiusens left a comment

Choose a reason for hiding this comment

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

Hi, thanks for this, there a few things to consider:

  • tests/integration/__init__.py sets abspaths for patchelf that would need the usr part stripped out.
  • if this really is a fix, the workaround that strips notes from binaries and retries in snapcraft/internal/elf.py should be.removed.

@cmatsuoka
Copy link
Contributor Author

This will require additional work. --set-interpreter is now working with patchelf bug 66 fixed, but bug 146/152 isn't and --set-rpath is making some binaries segfault.

Checking with readelf, we see the section layout in the gotty binary changing from:

  LOAD           0x00000000007e6000 0x0000000000be6000 0x0000000000be6000
                 0x0000000000083840 0x00000000000a5538  RW     0x1000
  DYNAMIC        0x00000000007e6140 0x0000000000be6140 0x0000000000be6140
                 0x0000000000000130 0x0000000000000130  RW     0x8

to

  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000003b1330 0x00000000003b1330  R E    0x1000
  DYNAMIC        0x0000000000000270 0x0000000000400270 0x0000000000400270
                 0x0000000000000140 0x0000000000000140  RW     0x8

which will still cause problems with cgo binaries.

Patchelf 0.10 is able to correctly set the interpreter, so the workaround
put in place for previous versions is no longer necessary.

Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
When building for classic confinement, relink dynamic go executables
so that patchelf will succeed when setting rpath.

Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
@codecov-io
Copy link

codecov-io commented Apr 4, 2019

Codecov Report

Merging #2519 into master will increase coverage by 0.02%.
The diff coverage is 88.88%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2519      +/-   ##
==========================================
+ Coverage   89.17%   89.19%   +0.02%     
==========================================
  Files         201      201              
  Lines       13615    13606       -9     
  Branches     2057     2057              
==========================================
- Hits        12141    12136       -5     
+ Misses       1039     1035       -4     
  Partials      435      435
Impacted Files Coverage Δ
snapcraft/plugins/go.py 94.91% <100%> (+0.13%) ⬆️
snapcraft/internal/elf.py 80.71% <80%> (-0.11%) ⬇️
snapcraft/internal/pluginhandler/_plugin_loader.py 84.69% <0%> (+2.04%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4900f73...ed23b6e. Read the comment docs.

@cmatsuoka
Copy link
Contributor Author

Instead of fixing patchelf to be able to set rpath in Go binaries, we changed the strategy to relink dynamic executables with the system linker so that patchelf will be able to handle them. Patchelf 0.10 is still needed to set the interpreter without the workarounds put in place for patchelf 0.9. This solves the rpath setting problem for binaries we build (but not for pre-built dynamic Go binaries already linked with the Go linker).

@sergiusens
Copy link
Collaborator

Looks good! Just wondering if you can add a spread test. Feel free to use the current cgo snap with a different spread task to make it classic, you can use the tooling to set a base and reset the yaml on restore as a template for setting confinement to classic.

snap/snapcraft.yaml Outdated Show resolved Hide resolved
sergiusens and others added 4 commits April 5, 2019 11:55
Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
fi

# Ensure binaries are properly patched
patchelf --print-rpath prime/bin/go-cgo | MATCH "/snap/core[0-9]*/current"
Copy link
Collaborator

Choose a reason for hiding this comment

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

make this /snap/snapcraft/current/bin/patchelf

Copy link
Collaborator

Choose a reason for hiding this comment

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

and if you really wanted some independence here, you you install binutils and use readelf for this :-)

Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
logger.debug("ELFFile({}) failed: {}".format(self.path, elf_error))
return False
else:
return "PT_DYNAMIC" in [s.header.p_type for s in ef.iter_segments()]
Copy link
Collaborator

Choose a reason for hiding this comment

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

just for reference, we also have https://github.com/snapcore/snapcraft/pull/2519/files#diff-f7cf307285f042f35434bbe680606c77R258 and those are all set as properties here https://github.com/snapcore/snapcraft/pull/2519/files#diff-f7cf307285f042f35434bbe680606c77R219 so it might be good to just do it on load, we can leave as is for now if we have a bug for this and a code comment TODO with the LP: # here

Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
@cmatsuoka cmatsuoka force-pushed the use-local-patchelf branch from 4096352 to 3e1289a Compare April 7, 2019 11:47
Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
@cmatsuoka cmatsuoka force-pushed the use-local-patchelf branch from 3e1289a to 1789b46 Compare April 7, 2019 12:53
snapcraft/plugins/go.py Outdated Show resolved Hide resolved
Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
@sergiusens sergiusens merged commit e39d240 into canonical:master Apr 8, 2019
xnox pushed a commit to xnox/snapcraft that referenced this pull request Jul 3, 2020
…onical#2519)

Pull patchelf from the latest stable tag from the upstream repository,
which contains patches critical for snapcraft to work properly with
Go ELF binaries.

Patchelf 0.10 is able to correctly set the interpreter, so the workaround
put in place for previous versions is no longer necessary.

When building for classic confinement, relink dynamic go executables
so that patchelf will succeed when setting rpath.

Noteworthy issues fixed in patchelf 0.10 are:

- Avoid inflating file sizes needlessly and allow binaries to be stripped
- patchelf --set-interpreter fails with `cannot find section` (canonical#66)
- --set-interpreter gives "cannot find section" for go binary (canonical#138)

LP: #1805205

Signed-off-by: Claudio Matsuoka <claudio.matsuoka@canonical.com>
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.

3 participants