]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
plugin-loader: Optionally use RTLD_NOW with dlopen()
authorTobias Brunner <tobias@strongswan.org>
Fri, 25 Sep 2015 09:05:24 +0000 (11:05 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 9 Nov 2015 13:37:08 +0000 (14:37 +0100)
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.

conf/options/charon.opt
src/libstrongswan/plugins/plugin_loader.c

index b00fe73b0dd97fb7713d14c26b27615e44d1b571..808e368b67bc004099f7ea372799571b5e76755a 100644 (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).
 
index f7ac347d2f7bad744314c49f8e3416897ea23861..01d0495bea5196fc4e080cc53fc61f77d5458e86 100644 (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());