Skip to content

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

Closed
@remexre

Description

@remexre
Contributor

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

Activity

added
O-muslTarget: The musl libc
A-linkageArea: linking into static, shared libraries and binaries
on Dec 13, 2020
mati865

mati865 commented on Dec 14, 2020

@mati865
Member

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

axonasif commented on Dec 14, 2020

@axonasif

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

remexre

remexre commented on Dec 14, 2020

@remexre
ContributorAuthor

@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

axonasif commented on Dec 14, 2020

@axonasif

@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

petrochenkov commented on Dec 14, 2020

@petrochenkov
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

workingjubilee commented on Feb 26, 2023

@workingjubilee
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

polarathene commented on Mar 7, 2024

@polarathene

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.O-muslTarget: The musl libc

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mati865@remexre@polarathene@petrochenkov@camelid

        Issue actions

          x86_64-unknown-linux-musl binaries have a DYNAMIC segment · Issue #80000 · rust-lang/rust