Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 29 Jul 2022 02:19:28 -0400
From: Christopher Sean Morrison <brlcad@....com>
To: musl@...ts.openwall.com
Subject: Re: dynamic linker is capturing "reserved" library names
 erroneously

Hi Rich,

> On Jul 28, 2022, at 8:07 PM, Rich Felker <dalias@...c.org> wrote:
> 
> As others have noted, the behavior of -lrt is defined as linking the standard library for realtime interfaces, not a user-defined library by that name.

Others have not stated that or I would have called the specific claim into scrutiny.  Unless my junk mail filter is being aggressive, there’s been only one reply prior.  As to the claim, though, that behavior is only mentioned in regards to the c99 utility and its compile-time link editor resolution.  There is no issue raised with regards to the c99 utility or compile-time symbol resolution.

Both gcc and clang indeed resolve symbols on musl at compile time without issue and consistent with their behavior on other platforms.  My example showed that intentionally.  The dynamic linker is what’s at issue and the standard says absolutely nothing about it from what I can see.

> The specification goes so far as to say, regarding use of -L to try to override that:
> 
>  If a directory specified by a -L option contains files with names
>  starting with any of the strings "libc.", "libl.", "libpthread.",
>  "libm.", "librt.", "libtrace.", "libxnet.", or "liby.", the results
>  are unspecified.

Again, you've quoted the ‘c99’ man page, yes?  As already mentioned, that page does not prescribe or imply any behavior on the dynamic linker or runtime resolution.  If defines how the c99 utility is to behave.  Moreover, if that’s to be taken as universal, it’s inconsistent with the ‘fort77’ man page that only calls out -L with a libf.a as being unspecified.  My example could just as well created librt using fort77 and still observed the same result.  The dynamic linker cannot satisfy both man pages without being inconsistent with one of them.   

> You may think it seems like it should be okay to use the name “librt" if you're not linking the standard -lrt

I do, and it’s been done successfully for over 40 years now across nearly every desktop and server platform in existence… The magnitude and implications of that timespan and portability exposure really seems to get lost on folks.  :)

> but imagine what would happen if you were on an implementation where some of the standard functions were defined in a discrete librt.so rather than all integrated in libc.so like musl does:

We don’t have to imagine as that was a common library configuration through the late 90’s and early 00’s.  As already mentioned, most issues are managed through path ordering (or one is intentionally overriding a library).

> This would cause very bad things to happen if someone copied the glibc versions of those libraries around with a glibc-linked program they were trying to use with ABI-compat, not aware that they were actually part of glibc and not third-party libraries the application needed.

This is a valid concern, though I would expect such a glibc-linked program to have an rpath set such that it’s not simply defaulting to DT_RUNPATH, ldconfig, or default paths.  Modern versions of GNU ld in fact require rpaths be set for relocation to work.  I think you’ve also described a situation where someone system-installed rather carelessly — installing an overriding librt/libm/libc/etc into /usr/lib is going to result in bad things happening on just about any platform and is not what’s being suggested.  Bad things will happen today on just about any Linux system if you copy an incompatible glibc from one system to another and install it in a location where it takes precedence.

It seems like the conflict in play is wanting glibc-compiled applications to just work when run on musl, hence the main reason why it appears to aggressively resolve the various libs at runtime regardless of the set rpath.  If you removed the dynamic override outright then one couldn’t just copy an executable over and expect it to work (would need to be recompiled or have their glibc installed for rpath to resolve), but that’s true today on other platforms.  It would behave like GNU ld.  It’s just convenient that glibc has been mostly ABI-compatible for a while, but that’s certainly not always the case and shouldn’t ever be assumed (imho).

> There is something of a long-term direction to decouple the ABI-compat stuff from musl, and I'm not sure if it would make sense to unreserve the names at the same time. A proposal to do this, like any proposal for supporting nonstandard functionality that could have unforseen consequences, would need to involve research into what those consequences might be, if any. It might end up being okay to do something like first hardening protection against loading glibc-linked libraries by those names (assuming they're the corresponding parts of the standard library from glibc) and then doing like you said, only using them as fallbacks after search.

I certainly wasn’t expecting this to be a quick and easy can of worms, but appreciate the consideration.  I maintain a simple expectation (these days) that users should be able to compile and link against libraries named anything, hence the simple program and library example.  The example demonstrably works on linux, mac windows, hpux, *bsd, haiku, etc.. and with good reason and implications.  This was mostly about opening a dialog for feedback.  Thanks for receiving and responding to the report.

Cheers!
Sean

p.s. for anyone finding this thread in the future couple workarounds are LD_PRELOAD or specify full paths when linking. for cmake, set CMP0060 to NEW.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.