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

x86_64-unknown-linux-musl binaries have a DYNAMIC segment #80000

Open
remexre opened this issue Dec 13, 2020 · 7 comments
Open

x86_64-unknown-linux-musl binaries have a DYNAMIC segment #80000

remexre opened this issue Dec 13, 2020 · 7 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. O-musl Target: The musl libc

Comments

@remexre
Copy link
Contributor

remexre commented Dec 13, 2020

On the current nightly and stable, compiling hello world with --target x86_64-unknown-linux-musl results in a static PIE binary that still has a DYNAMIC segment and .dynamic section. This causes file to report it as:

$ file /tmp/main
/tmp/main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, stripped

This was previously reported as #79624, which I believe to be incorrectly closed: on a hand-created binary without a DYNAMIC segment, file reports:

$ file out/fa6l
out/fa6l: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped
@remexre remexre added the C-bug Category: This is a bug. label Dec 13, 2020
@camelid camelid added O-musl Target: The musl libc A-linkage Area: linking into static, shared libraries and binaries labels Dec 13, 2020
@mati865
Copy link
Contributor

mati865 commented Dec 14, 2020

How have you "hand-created" your binary?
GCC creates PIE the similarly to Rust:

$ musl-gcc -pie hello.c -O2
$ file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, with debug_info, not stripped
$ readelf -S a.out | grep dynamic
  [17] .dynamic          DYNAMIC          0000000000003df0  00002df0

@axonasif
Copy link

@petrochenkov explained the reason at here: #79624 (comment)

@remexre
Copy link
Contributor Author

remexre commented Dec 14, 2020

@mati865 With Rust, of course :) https://git.sr.ht/~remexre/exps/tree/dbe21d43f7902d52bda5a0b3a72520075cd09c89/fa6l/bs/src/main.rs

@AXIM0S Yeah, I saw that; if you look at the #70740 PR that was linked, it shows the correct(?) behavior, from file at least.

@axonasif
Copy link

@mati865 With Rust, of course :) https://git.sr.ht/~remexre/exps/tree/dbe21d43f7902d52bda5a0b3a72520075cd09c89/fa6l/bs/src/main.rs

@AXIM0S Yeah, I saw that; if you look at the #70740 PR that was linked, it shows the correct(?) behavior, from file at least.

Yeah I know, it bothers me as well but the output binary does seem to work alike any other static binary, so guess I'll just ignore this for now or maybe it's file which needs an update over this ?

@petrochenkov
Copy link
Contributor

I didn't investigate why exactly static PIEs have the DYNAMIC segment, but given that they basically have a chunk of dynamic linker (rcrt1.o) statically compiled into them, it's not too surprising at least.
Feel free to investigate further, the source is available - https://github.com/ifduyue/musl/blob/master/crt/rcrt1.c, https://github.com/ifduyue/musl/blob/master/ldso/dlstart.c etc.

@workingjubilee
Copy link
Member

There doesn't seem to be anything that we need to change here, so long as the binaries remain functional? file is indeed probably applying an imperfect heuristic.

@polarathene
Copy link

TL;DR: Issue can be closed.


These two examples below are built against a basic cargo init example generated project, Rust 1.76.

DYNAMIC segment:

$ RUSTFLAGS="-C target-feature=+crt-static" cargo build --release --target x86_64-unknown-linux-musl

$ ldd target/x86_64-unknown-linux-musl/release/example
        /lib/ld-musl-x86_64.so.1 (0x7f48a7c05000)

$ file target/x86_64-unknown-linux-musl/release/example
target/x86_64-unknown-linux-musl/release/example: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), static-pie linked, BuildID[sha1]=09f3b38a44adfbf85bbd464aacc1a02570fb3f1c, with debug_info, not stripped

$ readelf -a target/x86_64-unknown-linux-musl/release/example | grep DYNAMIC
  [16] .dynamic          DYNAMIC          0000000000003e30  00002e30
  DYNAMIC        0x0000000000002e30 0x0000000000003e30 0x0000000000003e30
    37: 0000000000003e30     0 OBJECT  LOCAL  DEFAULT   16 _DYNAMIC

Now with additional flag -C relocation-model=static:

$ RUSTFLAGS="-C target-feature=+crt-static -C relocation-model=static" cargo build --release --target x86_64-unknown-linux-musl

# Musl ldd output has this line for actual static linked binaries:
$ ldd target/x86_64-unknown-linux-musl/release/example
/lib/ld-musl-x86_64.so.1: target/x86_64-unknown-linux-musl/release/example: Not a valid dynamic program

$ file target/x86_64-unknown-linux-musl/release/example
target/x86_64-unknown-linux-musl/release/example: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=3c869127ea497bcd2257ca9ba08bf4d8bab443fa, with debug_info, not stripped

# No output
$ readelf -a target/x86_64-unknown-linux-musl/release/example | grep DYNAMIC

Actual issue with the file program was resolved with file-5.38.

# You could use `docker cp` command to copy a binary from the host (or another container) to one of these to verify

# file-5.37:
docker run --rm -it alpine:3.11 ash -c 'apk add file && file -v'
# file-5.38:
docker run --rm -it alpine:3.12 ash -c 'apk add file && file -v'

But in prior versions if you do use -C relocation-model=static, it will not mistakenly output it as dynamically linked like shown in my earlier snippets 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. O-musl Target: The musl libc
Projects
None yet
Development

No branches or pull requests

7 participants