RFC: Treat RTLD_GLOBAL as unique to namespace when used with dlmopen
Carlos O'Donell
carlos@redhat.com
Fri Jul 24 18:43:00 GMT 2015
On 07/24/2015 05:29 AM, Michael Kerrisk (man-pages) wrote:
> On 07/16/2015 06:43 AM, Carlos O'Donell wrote:
>> Michael Kerrisk and I are working on a man page for dlmopen.
>
> See below for the current draft of the text describing dlmopen().
> Note that this text describes how Carlos and I think the API
> is supposed to behave (at least, I think the text fits with
> discussions Carlos and I had), and it's also consistent with
> actual Solaris behavior. The BUGS section describes the
> points that make dlmopen() unfit for purpose (IIUC).
>
> Cheers,
>
> Michael
>
>
>
> SYNOPSIS
> ....
> #define _GNU_SOURCE
> #include <dlfcn.h>
>
> void *dlmopen (Lmid_t lmid, const char *filename, int flags);
>
> Link with -ldl.
>
> DESCRIPTION
> dlopen()
> ...
> dlmopen()
> This function performs the same task as dlopen()âthe filename and
> flags arguments, as well as the return value, are the same,
> except for the differences noted below.
>
> The dlmopen() function differs from dlopen() primarily in that it
> accepts an additional argument, lmid, that specifies the link-map
> list (also referred to as a namespace) in which the shared object
> should be loaded. (By comparison, dlopen() adds the dynamically
> loaded shared object to the same namespace as the shared object
> from which the dlopen() call is made.) The Lmid_t type is an
> opaque handle that refers to a namespace.
>
> The lmid argument is either the ID of an existing namespace
> (which can be obtained using the dlinfo(3) RTLD_DI_LMID request)
> or one of the following special values:
>
> LM_ID_BASE
> Load the shared object in the initial namespace (i.e., the
> application's namespace).
>
> LM_ID_NEWLM
> Create a new namespace and load the shared object in that
> namespace. The object must have been correctly linked to
> reference all of the other shared objects that it
> requires, since the new namespace is initially empty.
>
> If handle is NULL, then the only permitted value for lmid is
> LM_ID_BASE.
What handle is NULL? If "filename" is NULL? This would be a glibc limitation
which we plan to fix in 2.23. We should certainly return the handle to the
base object loaded in the namespace as you suggest, just like the application
is returned upon dlopen (NULL).
>
> ....
>
> NOTES
> dlmopen() and namespaces
> A link-map list defines an isolated namespace for the resolution
> of symbols by the dynamic linker. Within a namespace, dependent
> shared objects are implicitly loaded according to the usual
> rules, and symbol references are likewise resolved according to
> the usual rules, but such resolution is confined to the definiâ
> tions provided by the objects that have been (explicitly and
> implicitly) loaded into the namespace.
>
> The dlmopen() function permits object-load isolationâthe ability
> to load a shared object in a new namespace without exposing the
> rest of the application to the symbols made available by the new
> object. Note that the use of the RTLD_LOCAL flag is not suffiâ
> cient for this purpose, since it prevents a shared object's symâ
> bols from being available to any other shared object. In some
> cases, we may want to make the symbols provided by a dynamically
> loaded shared object available to (a subset of) other shared
> objects without exposing those symbols to the entire application.
> This can be achieved by using a separate namespace and the
> RTLD_GLOBAL flag.
Lastly, RTLD_LOCAL loaded objects may be promoted to RTLD_GLOBAL if they
are dependencies of another RTLD_GLOBAL loaded object. Therefore RTLD_LOCAL
is still not sufficient to isolate the loaded shared object without explicit
control over all object dependencies.
>
> Possible uses of dlmopen() are plugins where the author of the
> plugin-loading framework can't trust the plugin authors and does
> not wish any undefined symbols from the plugin framework to be
> resolved to plugin symbols. Another use is to load the same
> object more than once. Without the use of dlmopen(), this would
> require the creation of distinct copies of the shared object
> file. Using dlmopen(), this can be achieved by loading the same
> shared object file into different namespaces.
>
> The glibc implementation supports a maximum of 16 namespaces.
>
> ...
> BUGS
> As at glibc 2.21, specifying the RTLD_GLOBAL flag when calling
> dlmopen() generates an error. Furthermore, specifying
> RTLD_GLOBAL when calling dlopen() results in a program crash
> (SIGSEGV) if the call is made from any object loaded in a namesâ
> pace other than the initial namespace.
>
Looks good to me. We need dlinfo documented also, which you already know,
but I wanted to make that explicit in this public discussion.
Cheers,
Carlos.
More information about the Libc-alpha
mailing list