Patchelf broke my binary?

Hi,

I made some changes to the snapcraft.yaml of my go snap to take advantage of the new patchelf-ing things in snapcraft. Unfortunately this broke my snap :frowning::

$ /snap/bin/go version
Segmentation fault (core dumped)

Poking and digging and gdbing and reading glibc source seems to suggest that this is because the PT_DYNAMIC header is pointing within a read-only segment:

$ readelf -l /snap/go/current/bin/go 
...
Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
...
  LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x3cc600 0x3cc600 R E 0x1000
  DYNAMIC        0x000270 0x0000000000400270 0x0000000000400270 0x000140 0x000140 RW  0x8
...

(compare with e.g. /bin/ls where the PT_DYNAMIC points into a writable segment:

$ readelf -l /bin/ls
...
Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
...
  LOAD           0x01de00 0x000000000061de00 0x000000000061de00 0x000800 0x001568 RW  0x200000
  DYNAMIC        0x01de18 0x000000000061de18 0x000000000061de18 0x0001e0 0x0001e0 RW  0x8
...

(You can get the broken snap here https://launchpad.net/~mwhudson/+snap/go110/+build/187373)

I have to assume that it was the patchelf invocation that did this. It seems rather unfortunate!

Pretty sure this is a patchelf bug, I created an upstream issue https://github.com/NixOS/patchelf/issues/146

I’ve worked around my issue by forcing external linking for the dynamic executables in the snap, so I guess this is mostly now just a heads up to watch out for this if any other snaps have the same problem.

1 Like

Thanks for doing the research here. The patching of ELF files could also be disabled with an entry for the part of

parts:
    part-name:
        build-attributes: [no-patchelf]

In case the behavior causes issues.