[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: /usr/bin/ld.so as a symbolic link for the dynamic loader



* Simon McVittie:

> On Thu, 02 Dec 2021 at 19:51:16 +0100, Florian Weimer wrote:
>> Having ld.so as a real command makes the name architecture-agnostic.
>> This discourages from hard-coding non-portable paths such as
>> /lib64/ld-linux-x86-64.so.2 or even (the non-ABI-compliant)
>> /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 in scripts that require
>> specific functionality offered by such an explicit loader invocation.
>
> This works up to a point, but because there is only one /usr/bin/ld.so,
> it can only work for one architecture per machine, so saying it's
> architecture-agnostic is still a bit of a stretch.

We can add a generic ELF parser to that ld.so and use PT_INTERP, as I
mentioned below.  I think this is the way to go.  Some care will be
needed to avoid endless loops, but that should be it.

Things will break if people link with --dynamic-linker=/usr/bin/ld.so,
but that's just broken (like using --dynamic-linker=/lib/dl-2.33.so
today).

>> In principle, it should
>> be possible to find PT_INTERP with a generic ELF parser and redirect to
>> that, but that's vaporware at present.  I don't know yet if it will be
>> possible to implement this without some knowledge of Debian's multi-arch
>> support in the loader.
>
> I believe Debian uses the interoperable (ABI-compliant) ELF interpreter
> as listed on https://sourceware.org/glibc/wiki/ABIList for all
> architectures - it certainly does for all *common* architectures (for
> example our x86_64 executables use /lib64/ld-linux-x86-64.so.2, which is
> a special exception to the rule that we don't usually use lib64).

I'm not aware of any Debian divergence yet, either.

If we can just run any specified PT_INTERP and use something else for
loop detection (e.g., an additional argument), then it should probably
work out of the box.  I was just trying to set expectations because I
had not really thought about it in detail, in particular the loop
avoidance scheme and it whether it must know about all the known
loaders.

Some distributions also want to avoid code execution from ldd.  Another
thing to consider before lifting paths out of PT_INTERP.

> I had naively believed that all distros do the same, but unfortunately
> my work on the Steam Runtime has taught me otherwise: for example, Arch
> Linux has a non-standard ELF interpreter /usr/lib/ld-linux-x86-64.so for
> executables that are built from the glibc source package (but uses the
> interoperable ELF interpreter for everything else),

/usr/lib/ld-linux-x86-64.so could be a botched attempt at completing
UsrMove.  The upstream makefiles are not really set up for that.

> and Exherbo consistently puts their dynamic linkers in
> /usr/x86_64-pc-linux-gnu/lib.

No idea about that one.

> Does glibc automatically set up the interoperable ELF interpreter, or is
> it something that distros' glibc maintainers have to "just know" if they
> are using a non-default ${libdir}?

With ./configure --prefix=/usr, upstream glibc is expected to use the
official path in the file system (and it should no longer be a symbolic
link, either).  The just-built binaries should use that path, too.

But the dynamic linker pathname is not entirely unique, which creates
problems for Debian-style multi-arch.

>> If someone wants to upstream the multi-arch patches, that would be
>> great.  glibc now accepts submissions under DCO, so copyright assignment
>> should no longer be an obstacle.
>
> (Please note that I am not a glibc maintainer and cannot speak for them.)
>
> I think multiarch is mostly build-time configuration rather than patches.
> The main thing needing patching is that we want ${LIB} to expand to
> lib/x86_64-linux-gnu instead of just x86_64-linux-gnu, so that the
> "/usr/${LIB}/libfoo.so.0" idiom works, but glibc would normally only take
> the last component of the ${libdir}:
>
> https://salsa.debian.org/glibc-team/glibc/-/blob/sid/debian/patches/any/local-ld-multiarch.diff

That must get the data from somewhere else.  Looking at

  <https://salsa.debian.org/glibc-team/glibc/-/blob/sid/debian/rules.d/build.mk>

it seems to come from DEB_HOST_MULTIARCH, and that's:

| DEB_HOST_MULTIARCH    ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)

We would have to take the table out of dpkg-architecture and put it into
upstream glibc (or gcc or binutils), otherwise you can't build a
multi-arch glibc on a non-Debian system.  Something like a generic
--with-multiarch-tuple= configure option would sidestep that, but risk
that different distributions end up with different multi-arch tuples.

> The freedesktop.org SDK used for Flatpak also uses Debian-style multiarch
> (but is not otherwise Debian-derived), and addresses that differently, in a
> way that might be more upstream-suitable:
>
> https://gitlab.com/freedesktop-sdk/freedesktop-sdk/-/blob/master/patches/glibc/fix-dl-dst-lib.patch

The use of realpath again assumes that the file system already contains
the answer, which is not true if you have a different architecture or
distribution.  It 's really not upstreamable, either.

In addition to get the right value for $LIB, it's also desirable to get
the default search paths right.  And there's also /usr/libexec/getconf
to worry about.

Thanks,
Florian


Reply to: