plugin-loader: Optionally use RTLD_NOW with dlopen()

This can be useful when writing custom plugins as typos or missing
linker flags that result in unresolved symbols in the shared object
could otherwise cause late crashes.  In particular, if such a symbol
is used in a code path that is rarely executed.  During development
and testing using RTLD_NOW instead of RTLD_LAZY will prevent the
plugin from getting loaded and makes the error visible immediately.
This commit is contained in:
Tobias Brunner 2015-09-25 11:05:24 +02:00
parent 7bea8e0f4a
commit 305c4aa82c
2 changed files with 15 additions and 6 deletions

View File

@ -65,6 +65,10 @@ charon.dh_exponent_ansi_x9_42 = yes
Use ANSI X9.42 DH exponent size or optimum size matched to cryptographic
strength.
charon.dlopen_use_rtld_now = no
Use RTLD_NOW with dlopen when loading plugins to reveal missing symbols
immediately.
charon.dns1
DNS server assigned to peer via configuration payload (CP).

View File

@ -356,6 +356,7 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
{
plugin_entry_t *entry;
void *handle;
int flag = RTLD_LAZY;
switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, critical, &entry))
{
@ -380,15 +381,19 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
return NULL;
}
}
handle = dlopen(file, RTLD_LAZY
if (lib->settings->get_bool(lib->settings, "%s.dlopen_use_rtld_now",
lib->ns, FALSE))
{
flag = RTLD_NOW;
}
#ifdef RTLD_NODELETE
/* if supported, do not unload library when unloading a plugin. It really
* doesn't matter in productive systems, but causes many (dependency)
* library reloads during unit tests. Some libraries can't handle that,
/* If supported, do not unload the library when unloading a plugin. It
* really doesn't matter in productive systems, but causes many (dependency)
* library reloads during unit tests. Some libraries can't handle that, e.g.
* GnuTLS leaks file descriptors in its library load/unload functions. */
| RTLD_NODELETE
flag |= RTLD_NODELETE;
#endif
);
handle = dlopen(file, flag);
if (handle == NULL)
{
DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror());