Message ID | 20210209171839.7911-14-vivek@collabora.com |
---|---|
State | New |
Headers | show |
Series | Implementation of RTLD_SHARED for dlmopen | expand |
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, >
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)) + { + 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,