]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
build: prevent unloading of dlopen'd modules
authorDaniel P. Berrangé <berrange@redhat.com>
Thu, 19 Apr 2018 10:42:22 +0000 (11:42 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Tue, 24 Apr 2018 15:59:45 +0000 (16:59 +0100)
We previously added "-z nodelete" to the build of libvirt.so to prevent
crashes when thread local destructors run which point to a code that
has been dlclose()d:

  commit 8e44e5593eb9b89fbc0b54fde15f130707a0d81e
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Thu Sep 1 17:57:06 2011 +0100

      Prevent crash from dlclose() of libvirt.so

The libvirtd loadable modules can suffer from the same problem if they
were ever unloaded. Fortunately we don't ever call dlclose() on them,
but lets add a second layer of protection by linking them with the
"-z nodelete" flag. While we're doing this, lets add a third layer of
protection by passing RTLD_NODELETE to dlopen().

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/Makefile.am
src/driver.c

index 2f8e5f690861e9e1d5559c22422cf67a69d3034e..0d8d380df13fc074ecc7d752233e12f7a46aa6f1 100644 (file)
@@ -51,7 +51,11 @@ AM_LDFLAGS = $(DRIVER_MODULES_LDFLAGS) \
                $(CYGWIN_EXTRA_LDFLAGS) \
                $(MINGW_EXTRA_LDFLAGS) \
                $(NULL)
-AM_LDFLAGS_MOD = -module -avoid-version $(AM_LDFLAGS)
+AM_LDFLAGS_MOD = \
+       -module \
+       -avoid-version \
+       $(LIBVIRT_NODELETE) \
+       $(AM_LDFLAGS)
 AM_LDFLAGS_MOD_NOUNDEF = $(AM_LDFLAGS_MOD) $(NO_UNDEFINED_LDFLAGS)
 
 POD2MAN = pod2man -c "Virtualization Support" -r "$(PACKAGE)-$(VERSION)"
index 52e1ae345abdb2d891b37934d7c1a1695dcfe6d9..7d4c78eaaaf8f46a03bb3685b84bfe38d4290e06 100644 (file)
@@ -45,6 +45,11 @@ static void *
 virDriverLoadModuleFile(const char *file)
 {
     void *handle = NULL;
+    int flags = RTLD_NOW | RTLD_GLOBAL;
+
+# ifdef RTLD_NODELETE
+    flags |= RTLD_NODELETE;
+# endif
 
     VIR_DEBUG("Load module file '%s'", file);
 
@@ -55,7 +60,7 @@ virDriverLoadModuleFile(const char *file)
 
     virUpdateSelfLastChanged(file);
 
-    if (!(handle = dlopen(file, RTLD_NOW | RTLD_GLOBAL)))
+    if (!(handle = dlopen(file, flags)))
         VIR_ERROR(_("failed to load module %s %s"), file, dlerror());
 
     return handle;