Re: [patch] Dangling Pointer in libltdl
Hi Ralf and thanks for looking at this! Thanks for the bug report. * Dave Brolley wrote on Thu, Jan 18, 2007 at 07:39:23PM CET: / / / The attached patch fixes a problem with a dangling pointer in lt_dlexit / / withing libltdl. The problem is that lt_dlclose is recursively called / / (via unload_deplibs) in order to close dependent libraries. One of these / / might be (and was for me!) the one pointed to by 'cur'./ I have trouble reproducing this bug easily. Which system does it happen on? It happened in a cygwin 1.6.9 environment on Windows XP Home edition. How does the graph formed by modules/libraries and interdependencies (linking against/dlopening) look like? The linked list looked at the time like this: lib1 - lib2 - lib3 - lib4 - etc. What happed was that 'cur' was at the head of the list (pointing at lib1). 'tmp' was then set to 'cur' and 'cur' was advanced to point to lib2. At this point lt_dlclose was called using 'tmp' to close lib1. This call determined that lib2 and lib3 were dependent libraries and they were closed (and removed from the list) by recursive calls to lt_dlclose. This left 'cur' pointing to unallocated memory which eventually caused a crash. In what order are things opened/linked against, which ones are closed explicitly, for this to trigger? Do you mix calls to lt_dlopen with direct calls to dlopen? Do you mix libraries created with libtool with libraries created without? These questions will take some time to sort out. Hopefully you can create a test case using the information I've given above in the mean time. The application in question is Red Hat's SID simulator (sources.redhat.com). Given time, I should be able to come up with a test case if necessary. / @@ -283,10 +283,19 @@ lt_dlexit (void)/ / {/ / ++errors;/ / }/ / }/ / }/ / + /* Make sure that the handle pointed to by 'cur' still exists./ / + lt_dlclose recursively closes dependent libraries which removes/ / + them from the linked list. One of these might be the one/ / + pointed to by 'cur'. *// / + for (tmp = handles; tmp; tmp = tmp-next)/ / + if (tmp == cur)/ / + break;/ / + if (! tmp)/ / + cur = handles;/ If the description is correct, the whole addition could go in the true branch of the `if (tmp-info.ref_count = level)' test, no? You are correct. I have attached a new patch which corrects this and also corrects a problem with my previous patch. My previous patch causes an infinite loop in the case that a resident library is in the linked list. In this case 'cur' gets reset to 'handles' when the end of the list is reached because 'tmp' ends up being NULL in my new loop. Because of the resident library, 'handles' is not NULL and the list is traversed repeatedly ad-infinitum. The fix is to make sure that 'cur' is not NULL before searching for it in the list. Thanks, Dave 2007-01-24 Dave Brolley [EMAIL PROTECTED] * libltdl/ltdl.c (lt_dlexit): Make sure that 'cur' is not NULL before checking that it is still in the list. Index: libltdl/ltdl.c === RCS file: /sources/libtool/libtool/libltdl/ltdl.c,v retrieving revision 1.245 diff -c -p -r1.245 ltdl.c *** libltdl/ltdl.c 13 Oct 2006 14:11:18 - 1.245 --- libltdl/ltdl.c 24 Jan 2007 21:52:46 - *** lt_dlexit (void) *** 283,288 --- 283,300 { ++errors; } + /* Make sure that the handle pointed to by 'cur' still exists. +lt_dlclose recursively closes dependent libraries which removes +them from the linked list. One of these might be the one +pointed to by 'cur'. */ + if (cur) + { + for (tmp = handles; tmp; tmp = tmp-next) + if (tmp == cur) + break; + if (! tmp) + cur = handles; + } } } } ___ Bug-libtool mailing list Bug-libtool@gnu.org http://lists.gnu.org/mailman/listinfo/bug-libtool
[patch] Dangling Pointer in libltdl
Hi, The attached patch fixes a problem with a dangling pointer in lt_dlexit withing libltdl. The problem is that lt_dlclose is recursively called (via unload_deplibs) in order to close dependent libraries. One of these might be (and was for me!) the one pointed to by 'cur'. The patch makes sure that the handle pointed to by 'cur' still exists in the linked list pointed to by 'handles' and, if it doesn't, resets it. This patch is against the latest CVS sources of the libtool project as of today. Dave 2007-01-17 Dave Brolley [EMAIL PROTECTED] * libltdl/ltdl.c (lt_dlexit): After each call to lt_dlclose, make sure that the handle pointed to by 'cur' still exists. Index: libltdl/ltdl.c === RCS file: /sources/libtool/libtool/libltdl/ltdl.c,v retrieving revision 1.245 diff -c -p -u -5 -r1.245 ltdl.c --- libltdl/ltdl.c 13 Oct 2006 14:11:18 - 1.245 +++ libltdl/ltdl.c 18 Jan 2007 18:31:21 - @@ -1,7 +1,7 @@ /* ltdl.c -- system independent dlopen wrapper - Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Originally by Thomas Tanner [EMAIL PROTECTED] NOTE: The canonical source of this file is maintained with the GNU Libtool package. Report bugs to [EMAIL PROTECTED] @@ -283,10 +283,19 @@ lt_dlexit (void) { ++errors; } } } + /* Make sure that the handle pointed to by 'cur' still exists. +lt_dlclose recursively closes dependent libraries which removes +them from the linked list. One of these might be the one +pointed to by 'cur'. */ + for (tmp = handles; tmp; tmp = tmp-next) + if (tmp == cur) + break; + if (! tmp) + cur = handles; } /* done if only resident modules are left */ if (!saw_nonresident) break; } ___ Bug-libtool mailing list Bug-libtool@gnu.org http://lists.gnu.org/mailman/listinfo/bug-libtool