From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27818 invoked by alias); 16 Sep 2006 18:38:30 -0000 Received: (qmail 27802 invoked by uid 22791); 16 Sep 2006 18:38:30 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 16 Sep 2006 18:38:25 +0000 Received: from sunsite.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.1/8.13.1) with ESMTP id k8GIcL7w007483; Sat, 16 Sep 2006 20:38:21 +0200 Received: (from jj@localhost) by sunsite.mff.cuni.cz (8.13.1/8.13.1/Submit) id k8GIcLwX007482; Sat, 16 Sep 2006 20:38:21 +0200 Date: Sat, 16 Sep 2006 18:38:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Test for a dlclose failure Message-ID: <20060916183820.GK4556@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2006-09/txt/msg00029.txt.bz2 Hi! This testcase segfaults in ld.so. When unload7mod2.so is loaded, it is added to unload7mod1.so's l_scope, but when it is dlclosed, nothing removes it from that scope. In _dl_close: else if (imap->l_type == lt_loaded) <= this condition is true { if (imap->l_searchlist.r_list == NULL <= this one is not && imap->l_initfini != NULL) <= this one is true { and therefore imap->l_scope isn't walked and adjusted. 2006-09-16 Jakub Jelinek * elf/Makefile: Add rules to build and run unload7 test. * elf/unload7.c: New test. * elf/unload7mod1.c: New file. * elf/unload7mod2.c: New file. --- libc/elf/Makefile.jj 2006-08-25 11:01:23.000000000 +0200 +++ libc/elf/Makefile 2006-09-16 20:19:06.000000000 +0200 @@ -87,6 +87,7 @@ distribute := rtld-Rules \ unload3mod1.c unload3mod2.c unload3mod3.c unload3mod4.c \ unload4mod1.c unload4mod2.c unload4mod3.c unload4mod4.c \ unload6mod1.c unload6mod2.c unload6mod3.c \ + unload7mod1.c unload7mod2.c \ tst-auditmod1.c tst-audit.sh \ order2mod1.c order2mod2.c order2mod3.c order2mod4.c \ tst-stackguard1.c tst-stackguard1-static.c \ @@ -168,7 +169,7 @@ tests += loadtest restest1 preloadtest l tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \ tst-dlmodcount tst-dlopenrpath tst-deep1 \ tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \ - unload3 unload4 unload5 unload6 tst-global1 order2 \ + unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \ tst-audit1 tst-audit2 \ tst-stackguard1 tst-addr1 # reldep9 @@ -211,6 +212,7 @@ modules-names = testobj1 testobj2 testob unload3mod1 unload3mod2 unload3mod3 unload3mod4 \ unload4mod1 unload4mod2 unload4mod3 unload4mod4 \ unload6mod1 unload6mod2 unload6mod3 \ + unload7mod1 unload7mod2 \ order2mod1 order2mod2 order2mod3 order2mod4 ifeq (yes,$(have-initfini-array)) modules-names += tst-array2dep tst-array5dep @@ -455,6 +457,8 @@ $(objpfx)unload4mod2.so: $(objpfx)unload $(objpfx)unload6mod1.so: $(libdl) $(objpfx)unload6mod2.so: $(libdl) $(objpfx)unload6mod3.so: $(libdl) +$(objpfx)unload7mod1.so: $(libdl) +$(objpfx)unload7mod2.so: $(objpfx)unload7mod1.so LDFLAGS-tst-tlsmod5.so = -nostdlib LDFLAGS-tst-tlsmod6.so = -nostdlib @@ -732,6 +736,10 @@ $(objpfx)unload6: $(libdl) $(objpfx)unload6.out: $(objpfx)unload6mod1.so $(objpfx)unload6mod2.so \ $(objpfx)unload6mod3.so +$(objpfx)unload7: $(libdl) +$(objpfx)unload7.out: $(objpfx)unload7mod1.so $(objpfx)unload7mod2.so +unload7-ENV = MALLOC_PERTURB_=85 + ifdef libdl $(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a $(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so --- libc/elf/unload7.c.jj 2006-09-16 19:58:48.000000000 +0200 +++ libc/elf/unload7.c 2006-09-16 20:03:31.000000000 +0200 @@ -0,0 +1,39 @@ +#include +#include + +int +main (void) +{ + void *h = dlopen ("unload7mod1.so", RTLD_LAZY); + if (h == NULL) + { + puts ("dlopen unload7mod1.so failed"); + return 1; + } + + int (*fn) (void); + fn = dlsym (h, "foo"); + if (fn == NULL) + { + puts ("dlsym failed"); + return 1; + } + + int ret = 0; + if (fn () == 0) + ++ret; + + void *h2 = dlopen ("unload7mod2.so", RTLD_LAZY); + if (h2 == NULL) + { + puts ("dlopen unload7mod1.so failed"); + return 1; + } + dlclose (h2); + + if (fn () == 0) + ++ret; + + dlclose (h); + return ret; +} --- libc/elf/unload7mod1.c.jj 2006-09-16 20:04:13.000000000 +0200 +++ libc/elf/unload7mod1.c 2006-09-16 20:06:26.000000000 +0200 @@ -0,0 +1,11 @@ +#include +#include + +int +foo (int i) +{ + if (dlsym (RTLD_DEFAULT, "unload7_nonexistent_symbol") == NULL) + return 1; + puts ("dlsym returned non-NULL"); + return 0; +} --- libc/elf/unload7mod2.c.jj 2006-09-16 20:06:51.000000000 +0200 +++ libc/elf/unload7mod2.c 2006-09-16 20:06:43.000000000 +0200 @@ -0,0 +1 @@ +int x; Jakub