[RFC,v8,13/20] Use the DSO search helper to check for preloaded DT_GNU_UNIQUE DSOs
Commit Message
If a DSO already exists (with the same name) in the base namespace
and it is flagged DT_GNU_UNIQUE then we should behave as if a proxy
had been requested.
---
elf/dl-open.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
Comments
On 09/02/2021 14:18, Vivek Das Mohapatra via Libc-alpha wrote:
> If a DSO already exists (with the same name) in the base namespace
> and it is flagged DT_GNU_UNIQUE then we should behave as if a proxy
> had been requested.
> ---
> elf/dl-open.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/elf/dl-open.c b/elf/dl-open.c
> index 441b8b1330..38b3587d4a 100644
> --- a/elf/dl-open.c
> +++ b/elf/dl-open.c
> @@ -484,6 +484,7 @@ dl_open_worker (void *a)
> const char *file = args->file;
> int mode = args->mode;
> struct link_map *call_map = NULL;
> + struct link_map *preloaded = NULL;
> int want_proxy = mode & RTLD_SHARED;
> Lmid_t proxy_ns = LM_ID_BASE;
>
> @@ -532,6 +533,23 @@ dl_open_worker (void *a)
> may not be true if this is a recursive call to dlopen. */
> _dl_debug_initialize (0, args->nsid);
>
> + /* Target Lmid is not the base and we haven't explicitly asked for a proxy:
> + We need to check for a matching DSO in the base Lmid in case it is flagged
> + DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE in which case we add RTLD_SHARED to the
> + mode and set want_proxy.
> + NOTE: RTLD_ISOLATE in the mode suppresses this behaviour. */
> + if (__glibc_unlikely (args->nsid != LM_ID_BASE) &&
> + __glibc_likely (!want_proxy))
'want_proxy' is an int, check against '0'.
> + {
> + preloaded = _dl_find_dso (file, LM_ID_BASE);
> +
> + if (preloaded && (preloaded->l_gnu_flags_1 & DF_GNU_1_UNIQUE))
No implicit checks.
> + {
> + want_proxy = RTLD_SHARED;
> + mode |= RTLD_SHARED;
> + }
> + }
> +
> /* Load the named object. */
> struct link_map *new;
> args->map = new = _dl_map_object (call_map, file, lt_loaded, 0,
>
@@ -484,6 +484,7 @@ dl_open_worker (void *a)
const char *file = args->file;
int mode = args->mode;
struct link_map *call_map = NULL;
+ struct link_map *preloaded = NULL;
int want_proxy = mode & RTLD_SHARED;
Lmid_t proxy_ns = LM_ID_BASE;
@@ -532,6 +533,23 @@ dl_open_worker (void *a)
may not be true if this is a recursive call to dlopen. */
_dl_debug_initialize (0, args->nsid);
+ /* Target Lmid is not the base and we haven't explicitly asked for a proxy:
+ We need to check for a matching DSO in the base Lmid in case it is flagged
+ DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE in which case we add RTLD_SHARED to the
+ mode and set want_proxy.
+ NOTE: RTLD_ISOLATE in the mode suppresses this behaviour. */
+ if (__glibc_unlikely (args->nsid != LM_ID_BASE) &&
+ __glibc_likely (!want_proxy))
+ {
+ preloaded = _dl_find_dso (file, LM_ID_BASE);
+
+ if (preloaded && (preloaded->l_gnu_flags_1 & DF_GNU_1_UNIQUE))
+ {
+ want_proxy = RTLD_SHARED;
+ mode |= RTLD_SHARED;
+ }
+ }
+
/* Load the named object. */
struct link_map *new;
args->map = new = _dl_map_object (call_map, file, lt_loaded, 0,