[RFC][PATCH v8 00/20] Implementation of RTLD_SHARED for dlmopen
Adhemerval Zanella
adhemerval.zanella@linaro.org
Thu Mar 4 18:27:01 GMT 2021
On 09/02/2021 14:18, Vivek Das Mohapatra via Libc-alpha wrote:
> This is a revision of a previous patchset that I posted here
> regarding https://sourceware.org/bugzilla/show_bug.cgi?id=22745
>
> Introduction:
>
> =======================================================================
> As discussed in the URL above dlmopen requires a mechanism for
> [optionally] sharing some objects between more than one namespace.
>
> The following patchset provides an implementation for this: If an
> object is loaded with the new RTLD_SHARED flag we instead ensure
> that a "master" copy exists (and is flagged as no-delete) in the
> main namespace and a thin wrapper or clone is placed in the target
> namespace.
>
> This patch series should address all the comments received on the
> earlier (v1) series, and fixes a bug in the previous (v2) series
> which left the r_debug struct in an inconsistent state when creating
> a proxy triggered the initial load of a DSO into the main namespace.
> =======================================================================
>
> In addition this patch series implements the following:
>
> - dlmopen will implicitly apply RTLD_SHARED to the libc/libpthread group
> (requires a patched binutils/ld so that the libc family DSOs can
> be flagged as requiring this behaviour)
>
> - binutils patchset accepted upstream;
> - https://sourceware.org/git/?p=binutils-gdb.git
> - commit 8a87b2791181eb7fc1533ffaeb95df8d87d41493
>
> - LD_AUDIT paths will NOT apply this implict sharing rule:
> audit libraries will continue to be completely isolated.
>
> - The mechanism for tagging DSOs as implicitly shared has been changed
> from a DT_FLAGS_1 flag to a DT_VALRNGHI/LO range dynamic section tag.
> (Based on feedback on the binutils side of this patch series).
>
> - DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE
>
> - A flag RTLD_ISOLATE which is used inernally to suppress RTLD_SHARED
> behaviour when audit libraries are being loaded, and is also made available
> to users who really want a completely separate copy of glibc in their new
> namespace.
>
> - Tests for the new dlmopen behaviour
>
> - Adds the unique dso flag to htl/libpthread.so as well as nptl
>
> I have not yet implemented, but plan to address once this series is
> accepted/acceptable:
>
> - Sensible RTLD_GLOBAL semantics for dlmopened DSOs in non-base namespaces
>
> - dl_iterate_ns_phdr (cf dl_iterate_phdr but taking a namespace argument)
>
> Vivek Das Mohapatra (20):
> Declare and describe the dlmopen RTLD_SHARED flag
> include/link.h: Update the link_map struct to allow proxies
> elf/dl-object.c: Implement a helper function to proxy link_map entries
> elf/dl-load.c, elf-dl-open.c: Implement RTLD_SHARED dlmopen proxying
> elf/dl-fini.c: Handle proxy link_map entries in the shutdown path
> elf/dl-init.c: Skip proxied link map entries in the dl init path
> elf/dl-open.c: Don't try libc linit in namespaces with no libc mapping
> elf/dl-open.c: when creating a proxy check the libc_map in NS 0
> Define a new dynamic section tag - DT_GNU_FLAGS_1
> Abstract the loaded-DSO search code into a private helper function
> Compare loaded DSOs by file ID and check for DF_GNU_1_UNIQUE
> Use the new DSO finder helper function since we have it
> Use the DSO search helper to check for preloaded DT_GNU_UNIQUE DSOs
> When loading DSOs into alternate namespaces check for DT_GNU_UNIQUE
> Suppress audit calls when a (new) namespace is empty
> Suppress inter-namespace DSO sharing for audit libraries
> dlsym, dlvsym should be able to look up symbols via DSO proxies
> Add DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE dynamic section+flag to glibc DSOs
> Add dlmopen / RTLD_SHARED tests
> Restore separate libc loading for the TLS/namespace storage test
Now that I have reviewed all the patches, I think the set should be reorganized
to each patch being logically consistent and not requiring to have all patches
applied in a bulk to get RTLD_SHARED/RTLD_ISOLATE support fully implemented.
So besides fixing all the implicit and style issues (missing space, attribute
out of 'if', etc.) I think the patch should be logically implemented as:
1. Move the 09/20 to first in set (it adds the new binutils definitions
and set the l_gnu_flags_1). The new definitions are used only
internally and the new flag is only set but not used on the patch.
2. Move the 10/20 to second in set (it adds a function used in subsequent
patch). It add a new function which is used on code refactoring.
3. Split the 12/20 a patch to do *just* the refactor that uses the
_dl_find_dso and move the RTLD_ISOLATE to the patch that actually
enables RTLD_SHARED.
4. Add a patch to add the DT_GNU_FLAGS_1 dynamic tag on the required
library (it should be safer since there is no logic yet that consumes it).
5. Combine all the remaining patch that enable RTLD_SHARED and RT_ISOLATE
on a single patch. It would be large patch, but it is more logically
consistent and easier to revert or backport.
6. Add the tests.
More information about the Libc-alpha
mailing list