mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] Running musl executables without a preinstalled dynamic linker
@ 2022-08-15 21:35 Colin Cross
  2022-08-20  9:43 ` Szabolcs Nagy
  0 siblings, 1 reply; 10+ messages in thread
From: Colin Cross @ 2022-08-15 21:35 UTC (permalink / raw)
  To: musl; +Cc: Ryan Prichard

I would like to distribute dynamic binaries built against musl to
systems that do not have the musl dynamic linker installed in any
known location (e.g. /lib/ld-musl-$ARCH.so.1).  I have two prototypes
that enable this, and I’d like to gauge whether either is something
that would be of interest to check in to musl, or whether it would be
something we should keep in our project.

The first solution is based on the embedded linker we use to test
bionic libc on non-Android systems.  The dynamic linker is compiled as
usual, then the resulting elf file is embedded as raw data into
Scrt1.o and the PT_INTERP section removed.  The entry point is changed
to point to a trampoline that modifies AT_BASE, AT_ENTRY and AT_PHDR
to simulate how the kernel would initialize them if the dynamic linker
was mapped separately by the kernel instead of as part of the main
executable, and then jumps to the dynamic linker.

This embedded linker solution works relatively well, except that the
dynamic linker’s elf sections are inside the main executable’s elf
sections, which can break reasonable assumptions.  For example, musl’s
dladdr fails to find symbols in the embedded linker, and gdb has
trouble finding debug information from the linker.  Musl’s reuse of
libc.so as the linker means that these problems apply to everything in
libc.so, and also increases the size of every binary by including all
of libc.so.

These problems with the embedded linker could be somewhat mitigated by
splitting the dynamic linker out of libc.so when using the embedded
linker.  That requires compiling the ldso sources against a statically
linked libc.a, tweaking some of the initialization, and forwarding the
dl* calls from libc.so to the separate linker.  The changes are
relatively small, but result in a pretty big difference in musl’s
internals with and without the embedded linker that may be hard to
maintain.

The second solution we call “relinterp”.  It was originally designed
by Ryan Prichard as a standalone trampoline that could be used with
musl, glibc or bionic, but I’ve more tightly integrated it with musl
in order to reuse CRTJMP for architecture portability and some of
musl’s string functions to reduce the size of the code.  It uses a
similar trampoline in Scrt1.o, but with a much larger implementation
that reads DT_RUNPATH to construct a path to the dynamic linker that
is relative to the executable.  It then maps the dynamic linker as the
kernel would, modifies AT_BASE, AT_ENTRY and AT_PHDR, and jumps to the
dynamic linker.

The current prototype of relinterp is tricky to compile, as it
requires using -fvisibility=hidden and ld -r partial linking to build
a Scrt1.o file that uses some of the src/string/*.c sources without
any relocations, and then objcopy –keep-global-symbol to hide the
string symbols.  It’s only useful if DT_RUNPATH contains $ORIGIN so
that the dynamic linker can be distributed alongside the executable,
so it is probably never going to be suitable for setuid binaries.

If relinterp were going to be included with musl I’d refactor it to
reuse the __dls* bootstrapping from dynlink.c so that it can link
against libc.a and not worry about avoiding any relocations.

An alternative solution to these two would be to distribute statically
linked binaries, which precludes the use of dlopen, or to wrap every
executable in a shell script that runs the dynamic linker directly.

Do either of these prototypes seem interesting enough to clean up and
post as upstream patches, or should I keep them as a side project that
I can bolt on to musl with minimal invasive changes?

Colin

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-09-27  5:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-15 21:35 [musl] Running musl executables without a preinstalled dynamic linker Colin Cross
2022-08-20  9:43 ` Szabolcs Nagy
2022-08-23  0:22   ` Colin Cross
2022-08-23  8:18     ` Szabolcs Nagy
2022-09-26 22:38       ` Colin Cross
2022-09-26 22:42         ` Colin Cross
2022-09-26 23:02           ` Rich Felker
2022-09-26 23:12             ` Colin Cross
2022-09-27  4:33               ` Colin Cross
2022-09-27  5:09                 ` Ridley Combs

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).