Red Hat Bugzilla – Bug 1007548
tnc client in wpa_supplicant does not dlopen with RTLD_GLOBAL
Last modified: 2014-06-18 00:34:40 EDT
+++ This bug was initially created as a clone of Bug #973315 +++
Description of problem:
when loading plugins (such as IMCs) with wpa_supplicant's tnc client, it causes symbols errors, because tnc client does not dlopen *.so modules with RTLD_GLOBAL.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. configure /etc/tnc_config with an IMC from strongswan
2. start wpa_supplicant
3. Observe the output and it shows that the IMC is not loaded correctly because some plugins failed to load.
IMC does not load properly.
IMC and it associated plugins should be loaded with out errors.
I'm asking upstream why it isn't RTLD_GLOBAL already, lets see what they say...
Also note that RTLD_GLOBAL creates the possibility of symbol clashes if plugins aren't careful about their symbol tables, and if multiple plugins from different sources are loaded, they must not conflict either.
So before we go further, what is the specific linker error that you're getting here?
What symbols does the plugin need that aren't available unless RTLD_GLOBAL is used?
What options is the TNC plugin that fails linked with?
(In reply to Dan Williams from comment #3)
> Also note that RTLD_GLOBAL creates the possibility of symbol clashes if
> plugins aren't careful about their symbol tables, and if multiple plugins
> from different sources are loaded, they must not conflict either.
> So before we go further, what is the specific linker error that you're
> getting here?
It gives following errors when loading /usr/lib64/strongimcv/imcvs/imc-os.so
specified in /etc/tnc_config.
/usr/lib64/strongimcv/plugins/libstrongswan-x509.so: undefined symbol: chunk_empty
[HSR] plugin 'openssl' failed to load: /usr/lib64/strongimcv/plugins/libstrongswan-openssl.so: undefined symbol: public_key_has_fingerprint
[HSR] plugin 'random' failed to load: /usr/lib64/strongimcv/plugins/libstrongswan-random.so: undefined symbol: dbg
[HSR] plugin 'nonce' failed to load: /usr/lib64/strongimcv/plugins/libstrongswan-nonce.so: undefined symbol: rng_quality_names
[HSR] plugin 'revocation' failed to load: /usr/lib64/strongimcv/plugins/libstrongswan-revocation.so: undefined symbol: chunk_empty
[HSR] plugin 'pem' failed to load: /usr/lib64/strongimcv/plugins/libstrongswan-pem.so: undefined symbol: chunk_empty
[HSR] plugin 'xcbc' failed to load: /usr/lib64/strongimcv/plugins/libstrongswan-xcbc.so: undefined symbol: chunk_empty
[HSR] added IETF attributes
[HSR] added ITA-HSR attributes
[HSR] libimcv initialized
[HSR] IMC 0 "OS" initialized
> What symbols does the plugin need that aren't available unless RTLD_GLOBAL
> is used?
> What options is the TNC plugin that fails linked with?
So for imc-os.c here are the linker flags:
imc_os_la_LDFLAGS = -module -avoid-version -no-undefined
as can be seen here:
At least for public_key_has_fingerprint(), the openssl plugin doesn't link against the implementation of that function.
The function is implemented in:
strongswan-5.1.1/src/libstrongswan/credentials/keys/public_key.c:bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint)
which is built as libstrongswan.la. But libstrongswan-openssl does not link to libstrongswan.la at all, and thus the symbol will not be resolved.
Same issue for libstrongswan-nonce.so not linking to libstrongswan to get rng_quality_names().
The plugins should be linking to all the symbols they actually need, they shouldn't be relying upon something magically linking in another plugin that provides the symbols they require, since that may not actually happen.
It might be as simple as doing the following in the plugins:
diff -up strongswan-5.1.1/src/libstrongswan/plugins/openssl/Makefile.am.foo strongswan-5.1.1/src/libstrongswan/plugins/openssl/Makefile.am
--- strongswan-5.1.1/src/libstrongswan/plugins/openssl/Makefile.am.foo 2013-11-05 11:14:33.472578538 -0600
+++ strongswan-5.1.1/src/libstrongswan/plugins/openssl/Makefile.am 2013-11-05 11:14:40.498490702 -0600
@@ -32,4 +32,6 @@ libstrongswan_openssl_la_SOURCES = \
libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
-libstrongswan_openssl_la_LIBADD = -lcrypto
+libstrongswan_openssl_la_LIBADD = -lcrypto \
(In reply to Dan Williams from comment #5)
> At least for public_key_has_fingerprint(), the openssl plugin doesn't link
> against the implementation of that function.
> The function is implemented in:
> public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint)
> which is built as libstrongswan.la. But libstrongswan-openssl does not link
> to libstrongswan.la at all, and thus the symbol will not be resolved.
> Same issue for libstrongswan-nonce.so not linking to libstrongswan to get
> The plugins should be linking to all the symbols they actually need, they
> shouldn't be relying upon something magically linking in another plugin that
> provides the symbols they require, since that may not actually happen.
> It might be as simple as doing the following in the plugins:
> diff -up strongswan-5.1.1/src/libstrongswan/plugins/openssl/Makefile.am.foo
> --- strongswan-5.1.1/src/libstrongswan/plugins/openssl/Makefile.am.foo
> 2013-11-05 11:14:33.472578538 -0600
> +++ strongswan-5.1.1/src/libstrongswan/plugins/openssl/Makefile.am
> 2013-11-05 11:14:40.498490702 -0600
> @@ -32,4 +32,6 @@ libstrongswan_openssl_la_SOURCES = \
> openssl_gcm.c openssl_gcm.h
> libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
> -libstrongswan_openssl_la_LIBADD = -lcrypto
> +libstrongswan_openssl_la_LIBADD = -lcrypto \
> + $(top_builddir)/src/libstrongswan/libstrongswan.la
I looked into the code in depth and this is not the correct way to fix it and here is the reason: libstrongswan "dlopens" all the plugins like libstrongswan-openssl, libstrongswan-nonce etc, so it is not right to link libstrongswan statically into the plugins.
The flow is like this:
wpa_supplicant "dlopens" imc-os.so (imc-os (or any other imc for that matter) is statically linked to libstrongswan), and then libstrongswan dlopens the other plugins.
Since wpa_supplicanr does not dlopen imc-os with RTDL_GLOBAL, the symbols in libstrongswan are not visible to the plugins.
So the only correct way to fix this is to have wpa_supplicant dlopen the imc-os (or any other IMC) with RTDL_GLOBAL.
Hope it helps.
This issue is breaking TNC testing on rhel7. I am not sure if I should mark it as blocker for rhel7.
I wasn't saying to statically libstrongswan into the plugins, I was saying to *dynamically* link them into the plugins. Adding LIBADD should not statically link them, it will dynamically link them due to libtool magic. That will cause the 'ldd' output of those plugin .sos to reference the main library in which those symbols are defined.
Another alternative is to split the utility functions out into a separate shared library that both libstrongswan *and* the plugins themselves can use.
I have tested a patch with strongimcv that addresses this issue so will change the component to strongimcv.
This has been fixed in Fedora rawhide/ 20/19, so closing now.
please disregard previous messages. I wanted to close the fedora bugs, but by mistake closed the rhel7 one.
This request was resolved in Red Hat Enterprise Linux 7.0.
Contact your manager or support representative in case you have further questions about the request.