Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1639611583.3fo4bm7va3.none@localhost>
Date: Wed, 15 Dec 2021 20:02:29 -0500
From: "Alex Xu (Hello71)" <alex_y_xu@...oo.ca>
To: musl@...ts.openwall.com
Subject: Satisfying DT_NEEDED from previous dlopens with explicit path

Hi,

Recently, Wine made a change that resulted in launching of any program 
to fail on musl. Specifically, it stopped ignoring the failure of dlsym 
on a NULL pointer which was returned from dlopen because library 
ws2_32.so could not be loaded because it has DT_NEEDED on ntdll.so which 
is not located in the system library paths but was previously 
successfully dlopened with an explicit path.

Currently, glibc, FreeBSD, NetBSD, and OpenBSD dynamic loaders allow 
this to succeed by satisfying DT_NEEDED dependencies if a previously 
dlopened library has the required DT_SONAME. I tested glibc and FreeBSD 
manually and inferred behavior from the NetBSD and OpenBSD sources.

FreeBSD: https://github.com/freebsd/freebsd-src/commit/0eb88f20298d056bf09b52ec2d84d3662b8fd152
NetBSD: https://github.com/NetBSD/src/commit/57fae3de47d379ffe8e38009a68e0b511e17cd5a
OpenBSD: https://github.com/openbsd/src/commit/0af06aaf0d91e6672e6f5dba4afd8f02e314f164

Windows requires all DLL names to be unique across the process. 
Using LoadLibrary with an explicit path will return a handle to an 
existing loaded library with the same filename if one exists. 
https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order: 
"If a DLL with the same module name is already loaded in memory, the 
system checks only for redirection and a manifest before resolving to 
the loaded DLL, no matter which directory it is in. The system does not 
search for the DLL."

Mac OS X/macOS uses "install_name" instead of DT_SONAME. This is 
normally a full path to the library, but can also use the placeholder 
@rpath. I believe this refers to the path by which it was found. Using 
this mechanism, plugins with the same name as a system library can be 
used as long as RTLD_LOCAL is specified in dlopen flags.

Haiku appears to satisfy DT_NEEDED dependencies based on the DT_SONAMEs 
of existing loaded libraries, and the original basenames for libraries 
which didn't contain DT_SONAME.

The behavior of satisfying DT_NEEDED using DT_SONAME is known to be used 
by Julia, OpenJDK, and Wine. Julia is currently broken on musl 
(https://github.com/JuliaLang/julia/issues/40556), OpenJDK works around 
it using LD_LIBRARY_PATH, and I believe Wine was always broken but the 
issue was silently ignored for most programs.

As I see it, the following options are available (or not):

0. musl cannot implement install_name because ELF doesn't have it. The 
   Windows behavior is bad and should not be implemented.
1. musl can implement DT_SONAME search, matching other ELF loaders.
2. Some applications may be able to use DT_RPATH or DT_RUNPATH with 
   $ORIGIN or $ORIGIN-relative paths. However, my understanding is that 
   Julia cannot do so, as the relative paths contain a value which is 
   not known until runtime.
3. The applications can use LD_LIBRARY_PATH. This doesn't work for the 
   same reason.
4. The applications could forgo DT_NEEDED entirely. The main downside of 
   this is that it would no longer be possible to use --no-undefined/-z 
   defs to diagnose missing symbols at compile time. It would also not 
   be possible to detect missing dependencies at runtime if they consist 
   entirely of weak symbols, but this seems unlikely.

Considering these factors, I believe musl should implement DT_SONAME 
search. A patch to implement it is available at 
https://github.com/JuliaLang/julia/issues/40556#issuecomment-825126303, 
but I think it would be simpler and use slightly less memory to re-use 
the existing shortname member which is currently unused for libraries 
loaded by explicit path.

Thanks,
Alex.

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.