This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCHv4][PING][BZ #17833] _dl_close_worker() does not release inconsistent objects.
- From: Pavel Kopyl <p dot kopyl at samsung dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>
- Cc: Yury Gribov <y dot gribov at samsung dot com>, GNU C Library <libc-alpha at sourceware dot org>, Carlos O'Donell <carlos at redhat dot com>, Roland McGrath <roland at hack dot frob dot com>, Viacheslav Garbuzov <v dot garbuzov at samsung dot com>
- Date: Fri, 29 May 2015 00:31:24 +0300
- Subject: Re: [PATCHv4][PING][BZ #17833] _dl_close_worker() does not release inconsistent objects.
- Authentication-results: sourceware.org; auth=none
- References: <54BD4F65 dot 2090108 at samsung dot com> <54BEF851 dot 70902 at redhat dot com> <54DBC3CB dot 5080703 at samsung dot com> <54F071DB dot 9040106 at samsung dot com> <20150301191710 dot GB19363 at vapier> <54F57B52 dot 6080202 at samsung dot com> <553A1BEE dot 6070705 at samsung dot com> <CAMe9rOqiyuyNAtJDZGbfs+0kk0j16-Vowp5f0z_x2zfsd76fMQ at mail dot gmail dot com> <5553382F dot 3020906 at samsung dot com> <5565B5E5 dot 7060101 at samsung dot com> <CAMe9rOr8yDpnHtRFbL3M56Sx5FWX-FVqEstnwsgtW6H+khvziQ at mail dot gmail dot com> <5565C2A8 dot 60306 at samsung dot com> <CAMe9rOq++pD-ugdYFEte49v8TLZEM505J+=WzPTOT_Lo-MdDHQ at mail dot gmail dot com> <5565C862 dot 1040003 at samsung dot com> <CAMe9rOo7TStj3SX8OK8s3H3G=2Pyr1WKTW=R-=SzVFBWY8PF0A at mail dot gmail dot com> <5566395A dot 3090605 at samsung dot com> <CAMe9rOp4Jrz4AE3-C5VmJ0PLmxoST3phyEQt3t59ag6UGbimBw at mail dot gmail dot com>
On 05/28/2015 01:06 AM, H.J. Lu wrote:
On Wed, May 27, 2015 at 2:38 PM, Pavel Kopyl <p.kopyl@samsung.com> wrote:
AFAIU DF_1_NODELETE change is necessary. Otherwise unique symbols force
library to remain loaded in half-initialized state (with missing
dependencies). This usecase is demonstrated by the testcase in patch.
But unique symbols != DF_1_NODELETE:
DF_1_NODELETE is set in do_lookup_unique at runtime (Paul, am I right?):
enter_unique_sym (entries, size,
new_hash, strtab + sym->st_name, sym, map);
if (map->l_type == lt_loaded)
/* Make sure we don't unload this object by
setting the appropriate flag. */
((struct link_map *) map)->l_flags_1 |= DF_1_NODELETE;
-Y
Should we set DF_1_NODELETE when dlopen fails? What happens
when dlopen a DF_1_NODELETE fails? Do we keep it in memory
even when dopen fails?
As I know there are following ways how to set DF_1_NODELETE flag for a
library.
1. Unique symbols.
2, Load with RTLD_NODELETE flag.
3. Link with "-z nodelete" option.
As for RTLD_NODELETE, there is no problem: dlopen exits in case of error
before DF_1_NODELETE is set.
If dlopen fails both in first and third cases this leads to locking
libraries in half-initialized state. I think this is a bug.
Suggested patch fixes both usecases.
Assume there is a problem with DF_1_NODELETE, which can be
set explicitly as well as implicitly. Your testcase only covers
implicitly DF_1_NODELETE, not explicitly DF_1_NODELETE.
I think we should verify the status of explicitly DF_1_NODELETE.
If explicitly DF_1_NODELETE works fine, then we only have a
problem with implicitly DF_1_NODELETE.
If explicitly DF_1_NODELETE doesn't work, we need to fix it
first and implicitly DF_1_NODELETE may just work.
Ok, I prepared the following testcase.
tst-nodelete.cc:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int
main (void)
{
int ret = 0;
/* This is a test for correct handling of dlopen failures for library
that
is loaded with RTLD_NODELETE flag. The first dlopen should fail
because
of undefined symbols in shared library. The second dlopen then
verifies
that library was properly unloaded. */
if (dlopen ("./tst-nodeletelib.so", RTLD_NOW | RTLD_NODELETE) != NULL
|| dlopen ("./tst-nodeletelib.so", RTLD_LAZY | RTLD_NOLOAD) != NULL)
{
printf("RTLD_NOLOAD test failed\n");
ret = 1;
}
/* This is a test for correct handling of dlopen failures for library
that
is linked with '-z nodelete' option and hence has DF_1_NODELETE flag.
The first dlopen should fail because of undefined symbols in shared
library. The second dlopen then verifies that library was properly
unloaded. */
if (dlopen ("./tst-znodeletelib.so", RTLD_NOW) != NULL
|| dlopen ("./tst-znodeletelib.so", RTLD_LAZY | RTLD_NOLOAD) != NULL)
{
printf("-z \'nodelete\' test failed\n");
ret = 1;
}
/* This is a test for correct handling of dlopen failures for library
with unique symbols. The first dlopen should fail because of undefined
symbols in shared library. The second dlopen then verifies that
library
was properly unloaded. */
if (dlopen ("./tst-unique5lib.so", RTLD_NOW) != NULL
|| dlopen ("./tst-unique5lib.so", RTLD_LAZY | RTLD_NOLOAD) != NULL)
{
printf("Unique symbols test failed\n");
ret = 1;
}
if (!ret)
printf ("SUCCESS\n");
return ret;
}
tst-unique5lib.cc:
extern int not_exist (void);
inline int make_unique (void)
{
/* Static variables in inline functions and classes
generate STB_GNU_UNIQUE symbols. */
static int unique;
return ++unique;
}
int foo (void)
{
return make_unique () + not_exist ();
}
tst-nodeletelib.cc:
extern int not_exist (void);
int foo (void)
{
return not_exist ();
}
g++ -o tst-nodelete tst-nodelete.cc -ldl
g++ -shared -fPIC -o tst-nodeletelib.so tst-nodeletelib.cc
g++ -shared -fPIC -Wl,-z,nodelete -o tst-znodeletelib.so tst-nodeletelib.cc
./tst-nodelete
-z 'nodelete' test failed
Unique symbols test failed
Thus, besides unique symbols we have a problem with explicitly
DF_1_NODELETE when library is built with "-Wl,-z,nodelete".
I checked that patch fixes this usecase too. Now I'm going to update
testcase in make check.
-Pavel