Closed asaaki closed 2 years ago
Running ./test-image
gave me a fail though:
--- Test case for sqlx:
ldd says:
/lib/ld-musl-x86_64.so.1 (0x7f87879d6000)
[FAIL] Executable is not static!
The command "bash ./test-image" exited with 1.
As you also mention in #98.
But I think that might be a red herring.
Here's an output of another binary (randomly chosen from /usr/bin) which does seem to be not fully static as it needs a libc on the system:
$ ldd /usr/bin/getconf
/lib/ld-musl-x86_64.so.1 (0x7fa18cd57000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fa18cd57000)
Interwebz says that we should also check the output of readelf
and look for INTERP
in the headers
It's part of the binutils, so has to be installed into the alpine stage.
$ readelf -l /usr/local/bin/using-sqlx
Elf file type is DYN (Shared object file)
Entry point 0x63062
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000062750 0x0000000000062750 R 0x1000
LOAD 0x0000000000063000 0x0000000000063000 0x0000000000063000
0x00000000002442bf 0x00000000002442bf R E 0x1000
LOAD 0x00000000002a8000 0x00000000002a8000 0x00000000002a8000
0x000000000013c4d0 0x000000000013c4d0 R 0x1000
LOAD 0x00000000003e4e20 0x00000000003e5e20 0x00000000003e5e20
0x0000000000053440 0x00000000000551e0 RW 0x1000
DYNAMIC 0x0000000000435c78 0x0000000000436c78 0x0000000000436c78
0x0000000000000130 0x0000000000000130 RW 0x8
NOTE 0x0000000000000270 0x0000000000000270 0x0000000000000270
0x0000000000000024 0x0000000000000024 R 0x4
TLS 0x00000000003e4e20 0x00000000003e5e20 0x00000000003e5e20
0x0000000000000005 0x00000000000002d8 R 0x20
GNU_EH_FRAME 0x0000000000377950 0x0000000000377950 0x0000000000377950
0x000000000000ba1c 0x000000000000ba1c R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x00000000003e4e20 0x00000000003e5e20 0x00000000003e5e20
0x00000000000531e0 0x00000000000531e0 R 0x1
using-sqlx has no INTERP there.
While …
readelf -l /usr/bin/getconf
Elf file type is DYN (Shared object file)
Entry point 0x22e8
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x0000000000000230 0x0000000000000230 R 0x8
INTERP 0x0000000000000270 0x0000000000000270 0x0000000000000270
0x0000000000000019 0x0000000000000019 R 0x1
[Requesting program interpreter: /lib/ld-musl-x86_64.so.1]
<snip>
… does have it, and you can even see a path encoded there.
From https://greek0.net/elf.html:
If an INTERP entry is present, the interpreter is loaded too. Statically linked binaries can do without an interpreter; […]
Another way to check is to run readelf -d <path/to/executable>
and look for (NEEDED)
, only dynamically linked programs should have entries, statically linked ones have none.
And yet another option is to use scanelf from pax-utils (scanelf -n <path>
, scanelf -i <path>
).
I also ran an example app in different variations of busybox:
FROM busybox
FROM busybox:musl
FROM busybox:uclibs
FROM busybox:glibc
And there are no problems, which I would expect if it was not truly static.
Even FROM scratch
works fine.
Fun fact:
ldd on alpine/musl is the following shell script:
$ cat /usr/bin/ldd
#!/bin/sh
exec /lib/ld-musl-x86_64.so.1 --list "$@"
So I believe that this lib/executable is injecting itself into the ldd output.
Last but not least I ran it under a debian:stretch-slim
and called ldd there:
ldd /usr/local/bin/using-sqlx
statically linked
(debian's ldd is a slightly more elaborate script.)
I adjusted the test-image script and the Dockerfiles of both static tests to use debian:stretch-slim for the better ldd checker.
Under asaaki/rust-musl-builder#1 you can see my travis runs, which are green for the proposed changes.
I've tested this updated image to build the diesel_cli
and it seems to work (thanks @asaaki !)
I wouldn't mind seeing this reviewed and merged (notable change: the updated openssl
library)
EDIT: worth mentioning that perhaps openssl could also be safely upgraded to latest 1.1.1k
(I've tested it and the built binary seems to be fine)
@jman-schief Updated to have 1.1.1k used.
Thank you to everyone for working on this, and to @asaaki for figuring out the static linking check! I've prepared a new PR inspired by this one but based off the latest main
branch. You can find it at https://github.com/emk/rust-musl-builder/pull/134.
I plan to release this when Rust 1.58.0 is released, to allowing existing users to easily stick with 1.57.0 if they want.
For some of the tiny tweaks and consistency changes do you want me to open new PRs after you merged your update PR?
(btw this one was already rebased to latest main, I can also undo some changes you don't like to make it into a mergeable state)
Use latest ubuntu LTS release (20.04)
Also:
Travis CI checks can be found under my PR of the fork: asaaki/rust-musl-builder#1 If you want to use the image already:
Closes #98