This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: RFC: Treat RTLD_GLOBAL as unique to namespace when used with dlmopen
- From: "Michael Kerrisk (man-pages)" <mtk dot manpages at gmail dot com>
- To: Carlos O'Donell <carlos at redhat dot com>, GNU C Library <libc-alpha at sourceware dot org>
- Cc: mtk dot manpages at gmail dot com
- Date: Fri, 24 Jul 2015 11:29:07 +0200
- Subject: Re: RFC: Treat RTLD_GLOBAL as unique to namespace when used with dlmopen
- Authentication-results: sourceware.org; auth=none
- References: <55A73673 dot 3060104 at redhat dot com>
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.
....
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.
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.
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/