[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: libltdl memory corruption
From: |
Ralf Wildenhues |
Subject: |
Re: libltdl memory corruption |
Date: |
Mon, 3 Mar 2008 22:53:49 +0100 |
User-agent: |
Mutt/1.5.17+20080114 (2008-01-14) |
Hello Andreas,
* Andreas Schwab wrote on Mon, Mar 03, 2008 at 03:39:47PM CET:
> libltdl uses memory after free when initialized twice.
Thank you very much for the bug report. Proposed patch below.
I tested it on i686-unknown-linux-gnu but it should be tested
with as many loaders as possible.
So I'd appreciate a review of this, and also test results on systems
with loaders other than preopen and dlopen. (I haven't even tested
successful compilation on those other systems.)
Thanks,
Ralf
2008-03-03 Ralf Wildenhues <address@hidden>
* libltdl/loaders/dld_link.c (vl_exit): New function, zero out ...
(vtable): ... this new file static variable split out from ...
(get_vtable): ... here. Initialize vtable, register vl_exit as
dlloader_exit function.
* libltdl/loaders/dlopen.c: Likewise.
* libltdl/loaders/dyld.c: Likewise.
* libltdl/loaders/load_add_on.c: Likewise.
* libltdl/loaders/loadlibrary.c: Likewise.
* libltdl/loaders/shl_load.c: Likewise.
* libltdl/loaders/preopen.c: Likewise; vl_exit existed here
already
* tests/lt_dlexit.at (lt_dlexit unloading libs): Update test.
Report by Andreas Schwab.
Index: libltdl/loaders/dld_link.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/loaders/dld_link.c,v
retrieving revision 1.9
diff -u -r1.9 dld_link.c
--- libltdl/loaders/dld_link.c 8 May 2007 14:38:50 -0000 1.9
+++ libltdl/loaders/dld_link.c 3 Mar 2008 21:41:03 -0000
@@ -1,7 +1,7 @@
/* loader-dld_link.c -- dynamic linking with dld
Copyright (C) 1998, 1999, 2000, 2004, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
Written by Thomas Tanner, 1998
NOTE: The canonical source of this file is maintained with the
@@ -45,20 +45,21 @@
/* Boilerplate code to set up the vtable for hooking this loader into
libltdl's loader list: */
+static int vl_exit (lt_user_data loader_data);
static lt_module vm_open (lt_user_data loader_data, const char *filename,
lt_dladvise advise);
static int vm_close (lt_user_data loader_data, lt_module module);
static void * vm_sym (lt_user_data loader_data, lt_module module,
const char *symbolname);
+static lt_dlvtable *vtable = 0;
+
/* Return the vtable for this loader, only the name and sym_prefix
attributes (plus the virtual function implementations, obviously)
change between loaders. */
lt_dlvtable *
get_vtable (lt_user_data loader_data)
{
- static lt_dlvtable *vtable = 0;
-
if (!vtable)
{
vtable = lt__zalloc (sizeof *vtable);
@@ -70,6 +71,7 @@
vtable->module_open = vm_open;
vtable->module_close = vm_close;
vtable->find_sym = vm_sym;
+ vtable->dlloader_exit = vl_exit;
vtable->dlloader_data = loader_data;
vtable->priority = LT_DLLOADER_APPEND;
}
@@ -92,6 +94,15 @@
# include <dld.h>
#endif
+/* A function called through the vtable when this loader is no
+ longer needed by the application. */
+static int
+vl_exit (lt_user_data LT__UNUSED loader_data)
+{
+ vtable = NULL;
+ return 0;
+}
+
/* A function called through the vtable to open a module with this
loader. Returns an opaque representation of the newly opened
module for processing with this loader's other vtable functions. */
Index: libltdl/loaders/dlopen.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/loaders/dlopen.c,v
retrieving revision 1.12
diff -u -r1.12 dlopen.c
--- libltdl/loaders/dlopen.c 12 Jan 2008 17:00:51 -0000 1.12
+++ libltdl/loaders/dlopen.c 3 Mar 2008 21:41:03 -0000
@@ -45,20 +45,21 @@
/* Boilerplate code to set up the vtable for hooking this loader into
libltdl's loader list: */
+static int vl_exit (lt_user_data loader_data);
static lt_module vm_open (lt_user_data loader_data, const char *filename,
lt_dladvise advise);
static int vm_close (lt_user_data loader_data, lt_module module);
static void * vm_sym (lt_user_data loader_data, lt_module module,
const char *symbolname);
+static lt_dlvtable *vtable = 0;
+
/* Return the vtable for this loader, only the name and sym_prefix
attributes (plus the virtual function implementations, obviously)
change between loaders. */
lt_dlvtable *
get_vtable (lt_user_data loader_data)
{
- static lt_dlvtable *vtable = 0;
-
if (!vtable)
{
vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
@@ -73,6 +74,7 @@
vtable->module_open = vm_open;
vtable->module_close = vm_close;
vtable->find_sym = vm_sym;
+ vtable->dlloader_exit = vl_exit;
vtable->dlloader_data = loader_data;
vtable->priority = LT_DLLOADER_PREPEND;
}
@@ -146,6 +148,17 @@
#define DL__SETERROR(errorcode) \
LT__SETERRORSTR (DLERROR (errorcode))
+
+/* A function called through the vtable when this loader is no
+ longer needed by the application. */
+static int
+vl_exit (lt_user_data LT__UNUSED loader_data)
+{
+ vtable = NULL;
+ return 0;
+}
+
+
/* A function called through the vtable to open a module with this
loader. Returns an opaque representation of the newly opened
module for processing with this loader's other vtable functions. */
Index: libltdl/loaders/dyld.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/loaders/dyld.c,v
retrieving revision 1.9
diff -u -r1.9 dyld.c
--- libltdl/loaders/dyld.c 4 Jul 2007 23:05:05 -0000 1.9
+++ libltdl/loaders/dyld.c 3 Mar 2008 21:41:04 -0000
@@ -1,7 +1,7 @@
/* loader-dyld.c -- dynamic linking on darwin and OS X
Copyright (C) 1998, 1999, 2000, 2004, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
Written by Peter O'Gorman, 1998
NOTE: The canonical source of this file is maintained with the
@@ -53,14 +53,14 @@
static void * vm_sym (lt_user_data loader_data, lt_module module,
const char *symbolname);
+static lt_dlvtable *vtable = 0;
+
/* Return the vtable for this loader, only the name and sym_prefix
attributes (plus the virtual function implementations, obviously)
change between loaders. */
lt_dlvtable *
get_vtable (lt_user_data loader_data)
{
- static lt_dlvtable *vtable = 0;
-
if (!vtable)
{
vtable = lt__zalloc (sizeof *vtable);
@@ -74,6 +74,7 @@
vtable->module_open = vm_open;
vtable->module_close = vm_close;
vtable->find_sym = vm_sym;
+ vtable->dlloader_exit = vl_exit;
vtable->dlloader_data = loader_data;
vtable->priority = LT_DLLOADER_APPEND;
}
@@ -181,6 +182,15 @@
static int dyld_cannot_close = 0;
+/* A function called through the vtable when this loader is no
+ longer needed by the application. */
+static int
+vl_exit (lt_user_data LT__UNUSED loader_data)
+{
+ vtable = NULL;
+ return 0;
+}
+
/* A function called through the vtable to initialise this loader. */
static int
vl_init (lt_user_data loader_data)
Index: libltdl/loaders/load_add_on.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/loaders/load_add_on.c,v
retrieving revision 1.9
diff -u -r1.9 load_add_on.c
--- libltdl/loaders/load_add_on.c 8 May 2007 14:38:50 -0000 1.9
+++ libltdl/loaders/load_add_on.c 3 Mar 2008 21:41:04 -0000
@@ -1,7 +1,7 @@
/* loader-load_add_on.c -- dynamic linking for BeOS
Copyright (C) 1998, 1999, 2000, 2004, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
Written by Thomas Tanner, 1998
NOTE: The canonical source of this file is maintained with the
@@ -45,20 +45,21 @@
/* Boilerplate code to set up the vtable for hooking this loader into
libltdl's loader list: */
+static int vl_exit (lt_user_data loader_data);
static lt_module vm_open (lt_user_data loader_data, const char *filename,
lt_dladvise advise);
static int vm_close (lt_user_data loader_data, lt_module module);
static void * vm_sym (lt_user_data loader_data, lt_module module,
const char *symbolname);
+static lt_dlvtable *vtable = 0;
+
/* Return the vtable for this loader, only the name and sym_prefix
attributes (plus the virtual function implementations, obviously)
change between loaders. */
lt_dlvtable *
get_vtable (lt_user_data loader_data)
{
- static lt_dlvtable *vtable = 0;
-
if (!vtable)
{
vtable = lt__zalloc (sizeof *vtable);
@@ -70,6 +71,7 @@
vtable->module_open = vm_open;
vtable->module_close = vm_close;
vtable->find_sym = vm_sym;
+ vtable->dlloader_exit = vl_exit;
vtable->dlloader_data = loader_data;
vtable->priority = LT_DLLOADER_APPEND;
}
@@ -90,6 +92,15 @@
#include <kernel/image.h>
+/* A function called through the vtable when this loader is no
+ longer needed by the application. */
+static int
+vl_exit (lt_user_data LT__UNUSED loader_data)
+{
+ vtable = NULL;
+ return 0;
+}
+
/* A function called through the vtable to open a module with this
loader. Returns an opaque representation of the newly opened
module for processing with this loader's other vtable functions. */
Index: libltdl/loaders/loadlibrary.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/loaders/loadlibrary.c,v
retrieving revision 1.15
diff -u -r1.15 loadlibrary.c
--- libltdl/loaders/loadlibrary.c 8 May 2007 14:38:50 -0000 1.15
+++ libltdl/loaders/loadlibrary.c 3 Mar 2008 21:41:04 -0000
@@ -1,7 +1,7 @@
/* loader-loadlibrary.c -- dynamic linking for Win32
Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
Written by Thomas Tanner, 1998
NOTE: The canonical source of this file is maintained with the
@@ -49,6 +49,7 @@
/* Boilerplate code to set up the vtable for hooking this loader into
libltdl's loader list: */
+static int vl_exit (lt_user_data loader_data);
static lt_module vm_open (lt_user_data loader_data, const char *filename,
lt_dladvise advise);
static int vm_close (lt_user_data loader_data, lt_module module);
@@ -56,6 +57,7 @@
const char *symbolname);
static lt_dlinterface_id iface_id = 0;
+static lt_dlvtable *vtable = 0;
/* Return the vtable for this loader, only the name and sym_prefix
attributes (plus the virtual function implementations, obviously)
@@ -63,8 +65,6 @@
lt_dlvtable *
get_vtable (lt_user_data loader_data)
{
- static lt_dlvtable *vtable = 0;
-
if (!vtable)
{
vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
@@ -77,6 +77,7 @@
vtable->module_open = vm_open;
vtable->module_close = vm_close;
vtable->find_sym = vm_sym;
+ vtable->dlloader_exit = vl_exit;
vtable->dlloader_data = loader_data;
vtable->priority = LT_DLLOADER_APPEND;
}
@@ -97,6 +98,15 @@
#include <windows.h>
+/* A function called through the vtable when this loader is no
+ longer needed by the application. */
+static int
+vl_exit (lt_user_data LT__UNUSED loader_data)
+{
+ vtable = NULL;
+ return 0;
+}
+
/* A function called through the vtable to open a module with this
loader. Returns an opaque representation of the newly opened
module for processing with this loader's other vtable functions. */
Index: libltdl/loaders/preopen.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/loaders/preopen.c,v
retrieving revision 1.16
diff -u -r1.16 preopen.c
--- libltdl/loaders/preopen.c 30 Aug 2007 18:39:10 -0000 1.16
+++ libltdl/loaders/preopen.c 3 Mar 2008 21:41:04 -0000
@@ -1,7 +1,7 @@
/* loader-preopen.c -- emulate dynamic linking using preloaded_symbols
Copyright (C) 1998, 1999, 2000, 2004, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
Written by Thomas Tanner, 1998
NOTE: The canonical source of this file is maintained with the
@@ -53,14 +53,14 @@
static void * vm_sym (lt_user_data loader_data, lt_module module,
const char *symbolname);
+static lt_dlvtable *vtable = 0;
+
/* Return the vtable for this loader, only the name and sym_prefix
attributes (plus the virtual function implementations, obviously)
change between loaders. */
lt_dlvtable *
get_vtable (lt_user_data loader_data)
{
- static lt_dlvtable *vtable = 0;
-
if (!vtable)
{
vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
@@ -132,6 +132,7 @@
static int
vl_exit (lt_user_data LT__UNUSED loader_data)
{
+ vtable = NULL;
free_symlists ();
return 0;
}
Index: libltdl/loaders/shl_load.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/loaders/shl_load.c,v
retrieving revision 1.10
diff -u -r1.10 shl_load.c
--- libltdl/loaders/shl_load.c 8 May 2007 14:38:50 -0000 1.10
+++ libltdl/loaders/shl_load.c 3 Mar 2008 21:41:04 -0000
@@ -1,7 +1,7 @@
/* loader-shl_load.c -- dynamic linking with shl_load (HP-UX)
Copyright (C) 1998, 1999, 2000, 2004, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008 Free Software Foundation, Inc.
Written by Thomas Tanner, 1998
NOTE: The canonical source of this file is maintained with the
@@ -45,20 +45,21 @@
/* Boilerplate code to set up the vtable for hooking this loader into
libltdl's loader list: */
+static int vl_exit (lt_user_data loader_data);
static lt_module vm_open (lt_user_data loader_data, const char *filename,
lt_dladvise advise);
static int vm_close (lt_user_data loader_data, lt_module module);
static void * vm_sym (lt_user_data loader_data, lt_module module,
const char *symbolname);
+static lt_dlvtable *vtable = 0;
+
/* Return the vtable for this loader, only the name and sym_prefix
attributes (plus the virtual function implementations, obviously)
change between loaders. */
lt_dlvtable *
get_vtable (lt_user_data loader_data)
{
- static lt_dlvtable *vtable = 0;
-
if (!vtable)
{
vtable = lt__zalloc (sizeof *vtable);
@@ -70,6 +71,7 @@
vtable->module_open = vm_open;
vtable->module_close = vm_close;
vtable->find_sym = vm_sym;
+ vtable->dlloader_exit = vl_exit;
vtable->dlloader_data = loader_data;
vtable->priority = LT_DLLOADER_APPEND;
}
@@ -133,6 +135,15 @@
#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
+/* A function called through the vtable when this loader is no
+ longer needed by the application. */
+static int
+vl_exit (lt_user_data LT__UNUSED loader_data)
+{
+ vtable = NULL;
+ return 0;
+}
+
/* A function called through the vtable to open a module with this
loader. Returns an opaque representation of the newly opened
module for processing with this loader's other vtable functions. */
Index: tests/lt_dlexit.at
===================================================================
RCS file: /cvsroot/libtool/libtool/tests/lt_dlexit.at,v
retrieving revision 1.10
diff -u -r1.10 lt_dlexit.at
--- tests/lt_dlexit.at 1 Mar 2008 22:43:04 -0000 1.10
+++ tests/lt_dlexit.at 3 Mar 2008 21:41:04 -0000
@@ -32,6 +32,7 @@
# Test for
# http://lists.gnu.org/archive/html/bug-libtool/2007-01/msg00014.html
+# http://lists.gnu.org/archive/html/bug-libtool/2008-03/msg00013.html
AT_DATA([main.c],
[[#include <ltdl.h>
@@ -80,6 +81,14 @@
fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
return 1;
}
+ if (lt_dlexit() != 0) {
+ fprintf (stderr, "error during first lt_dlexit: %s\n", lt_dlerror());
+ return 1;
+ }
+ if (lt_dlinit() != 0) {
+ fprintf (stderr, "error during second initialization: %s\n", lt_dlerror());
+ return 1;
+ }
if (!(b1 = xdlopen ("modb1.la"))) return 1;
if (xdlsymtest (b1, "fb1", "vb1")) return 1;
/* do not lt_dlclose here on purpose. */