[libvirt] [PATCH 03/14] build: prevent unloading of dlopen'd modules

Daniel P. Berrangé posted 14 patches 7 years ago
[libvirt] [PATCH 03/14] build: prevent unloading of dlopen'd modules
Posted by Daniel P. Berrangé 7 years ago
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 384b9a76a5e387f64cfe8f83f4a518bb302e80f7
  Author: Daniel P. Berrangé <berrange@redhat.com>
  Date:   Thu Apr 19 11:42:22 2018 +0100

    driver: prevent unloading of dlopen'd modules

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 | 6 +++++-
 src/driver.c    | 7 ++++++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 2f8e5f6908..0d8d380df1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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)"
diff --git a/src/driver.c b/src/driver.c
index 52e1ae345a..7d4c78eaaa 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -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;
-- 
2.14.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 03/14] build: prevent unloading of dlopen'd modules
Posted by Michal Privoznik 7 years ago
On 04/19/2018 07:09 PM, Daniel P. Berrangé wrote:
> 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 384b9a76a5e387f64cfe8f83f4a518bb302e80f7
>   Author: Daniel P. Berrangé <berrange@redhat.com>
>   Date:   Thu Apr 19 11:42:22 2018 +0100
> 
>     driver: prevent unloading of dlopen'd modules

As I've pointed earlier no such commit exists.

> 
> 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 | 6 +++++-
>  src/driver.c    | 7 ++++++-
>  2 files changed, 11 insertions(+), 2 deletions(-)

ACK

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list