This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.21-567-g02d5e5d


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  02d5e5d94a78d32e940dfb3b58ab7f06c31b0f76 (commit)
      from  890b7a4b33d482b5c768ab47d70758b80227e9bc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=02d5e5d94a78d32e940dfb3b58ab7f06c31b0f76

commit 02d5e5d94a78d32e940dfb3b58ab7f06c31b0f76
Author: Pavel Kopyl <p.kopyl@samsung.com>
Date:   Tue Jul 7 18:45:46 2015 +0300

    Add forced deletion support to _dl_close_worker
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=17833
    
    I've a shared library that contains both undefined and unique symbols.
    Then I try to call the following sequence of dlopen:
    
    1. dlopen("./libfoo.so", RTLD_NOW)
    2. dlopen("./libfoo.so", RTLD_LAZY | RTLD_GLOBAL)
    
    First dlopen call terminates with error because of undefined symbols,
    but STB_GNU_UNIQUE ones set DF_1_NODELETE flag and hence block library
    in the memory.
    
    The library goes into inconsistent state as several structures remain
    uninitialized. For instance, relocations for GOT table were not performed.
    
    By the time of second dlopen call this library looks like as it would be
    fully initialized but this is not true: any call through incorrect GOT
    table leads to segmentation fault.  On some systems this inconsistency
    triggers assertions in the dynamic linker.
    
    This patch adds a parameter to _dl_close_worker to implement forced object
    deletion in case of dlopen() failure:
    
    1. Clears DF_1_NODELETE bit if forced, to allow library to be removed from
    memory.
    2. For each unique symbol that is defined in this object clears
    appropriate entry in _ns_unique_sym_table.
    
    	[BZ #17833]
    	* elf/Makefile (tests): Add tst-nodelete.
    	(modules-names): Add tst-nodelete-uniquemod.
    	(tst-nodelete-uniquemod.so-no-z-defs): New.
    	(tst-nodelete-rtldmod.so-no-z-defs): Likewise.
    	(tst-nodelete-zmod.so-no-z-defs): Likewise.
    	($(objpfx)tst-nodelete): Likewise.
    	($(objpfx)tst-nodelete.out): Likewise.
    	(LDFLAGS-tst-nodelete): Likewise.
    	(LDFLAGS-tst-nodelete-zmod.so): Likewise.
    	* elf/dl-close.c (_dl_close_worker): Add a parameter to
    	implement forced object deletion.
    	(_dl_close): Pass false to _dl_close_worker.
    	* elf/dl-open.c (_dl_open): Pass true to _dl_close_worker.
    	* elf/tst-nodelete.cc: New file.
    	* elf/tst-nodeletelib.cc: Likewise.
    	* elf/tst-znodeletelib.cc: Likewise.
    	* include/dlfcn.h (_dl_close_worker): Add a new parameter.

diff --git a/ChangeLog b/ChangeLog
index ff64fdc..2ccf739 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2015-07-07  Pavel Kopyl  <p.kopyl@samsung.com>
+	    Mikhail Ilin  <m.ilin@samsung.com>
+
+	[BZ #17833]
+	* elf/Makefile (tests): Add tst-nodelete.
+	(modules-names): Add tst-nodelete-uniquemod.
+	(tst-nodelete-uniquemod.so-no-z-defs): New.
+	(tst-nodelete-rtldmod.so-no-z-defs): Likewise.
+	(tst-nodelete-zmod.so-no-z-defs): Likewise.
+	($(objpfx)tst-nodelete): Likewise.
+	($(objpfx)tst-nodelete.out): Likewise.
+	(LDFLAGS-tst-nodelete): Likewise.
+	(LDFLAGS-tst-nodelete-zmod.so): Likewise.
+	* elf/dl-close.c (_dl_close_worker): Add a parameter to
+	implement forced object deletion.
+	(_dl_close): Pass false to _dl_close_worker.
+	* elf/dl-open.c (_dl_open): Pass true to _dl_close_worker.
+	* elf/tst-nodelete.cc: New file.
+	* elf/tst-nodeletelib.cc: Likewise.
+	* elf/tst-znodeletelib.cc: Likewise.
+	* include/dlfcn.h (_dl_close_worker): Add a new parameter.
+
 2015-07-07  Stefan Liebler  <stli@linux.vnet.ibm.com>
 
 	[BZ #18508]
diff --git a/NEWS b/NEWS
index 07e8bd8..a809ce2 100644
--- a/NEWS
+++ b/NEWS
@@ -14,19 +14,19 @@ Version 2.22
   16526, 16538, 16559, 16560, 16704, 16783, 16850, 17053, 17090, 17195,
   17269, 17293, 17322, 17403, 17523, 17542, 17569, 17581, 17588, 17596,
   17620, 17621, 17628, 17631, 17692, 17711, 17715, 17776, 17779, 17792,
-  17836, 17841, 17912, 17916, 17930, 17932, 17944, 17949, 17964, 17965,
-  17967, 17969, 17977, 17978, 17987, 17991, 17996, 17998, 17999, 18007,
-  18019, 18020, 18029, 18030, 18032, 18034, 18036, 18038, 18039, 18042,
-  18043, 18046, 18047, 18049, 18068, 18080, 18093, 18100, 18104, 18110,
-  18111, 18116, 18125, 18128, 18138, 18185, 18196, 18197, 18206, 18210,
-  18211, 18217, 18219, 18220, 18221, 18234, 18244, 18245, 18247, 18287,
-  18319, 18324, 18333, 18346, 18371, 18397, 18409, 18410, 18412, 18418,
-  18422, 18434, 18435, 18444, 18468, 18469, 18470, 18479, 18483, 18495,
-  18496, 18497, 18498, 18502, 18507, 18508, 18512, 18513, 18519, 18520,
-  18522, 18527, 18528, 18529, 18530, 18532, 18533, 18534, 18536, 18539,
-  18540, 18542, 18544, 18545, 18546, 18547, 18549, 18553, 18558, 18569,
-  18583, 18585, 18586, 18592, 18593, 18594, 18602, 18612, 18613, 18619,
-  18633.
+  17833, 17836, 17841, 17912, 17916, 17930, 17932, 17944, 17949, 17964,
+  17965, 17967, 17969, 17977, 17978, 17987, 17991, 17996, 17998, 17999,
+  18007, 18019, 18020, 18029, 18030, 18032, 18034, 18036, 18038, 18039,
+  18042, 18043, 18046, 18047, 18049, 18068, 18080, 18093, 18100, 18104,
+  18110, 18111, 18116, 18125, 18128, 18138, 18185, 18196, 18197, 18206,
+  18210, 18211, 18217, 18219, 18220, 18221, 18234, 18244, 18245, 18247,
+  18287, 18319, 18324, 18333, 18346, 18371, 18397, 18409, 18410, 18412,
+  18418, 18422, 18434, 18435, 18444, 18468, 18469, 18470, 18479, 18483,
+  18495, 18496, 18497, 18498, 18502, 18507, 18508, 18512, 18513, 18519,
+  18520, 18522, 18527, 18528, 18529, 18530, 18532, 18533, 18534, 18536,
+  18539, 18540, 18542, 18544, 18545, 18546, 18547, 18549, 18553, 18558,
+  18569, 18583, 18585, 18586, 18592, 18593, 18594, 18602, 18612, 18613,
+  18619, 18633.
 
 * Cache information can be queried via sysconf() function on s390 e.g. with
   _SC_LEVEL1_ICACHE_SIZE as argument.
diff --git a/elf/Makefile b/elf/Makefile
index f21276c..bd0f24d 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -132,7 +132,7 @@ tests += $(tests-static)
 ifeq (yes,$(build-shared))
 tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 	 constload1 order noload filter unload \
-	 reldep reldep2 reldep3 reldep4 nodelete nodelete2 \
+	 reldep reldep2 reldep3 reldep4 nodelete nodelete2 tst-nodelete \
 	 nodlopen nodlopen2 neededtest neededtest2 \
 	 neededtest3 neededtest4 unload2 lateglobal initfirst global \
 	 restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
@@ -207,7 +207,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
 		tst-unique1mod1 tst-unique1mod2 \
 		tst-unique2mod1 tst-unique2mod2 \
 		tst-auditmod9a tst-auditmod9b \
-		$(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib) \
+		$(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
+		  tst-nodelete-uniquemod) \
+		tst-nodelete-rtldmod tst-nodelete-zmod \
 		tst-initordera1 tst-initorderb1 \
 		tst-initordera2 tst-initorderb2 \
 		tst-initordera3 tst-initordera4 \
@@ -591,6 +593,9 @@ ifuncmod5.so-no-z-defs = yes
 ifuncmod6.so-no-z-defs = yes
 tst-auditmod9a.so-no-z-defs = yes
 tst-auditmod9b.so-no-z-defs = yes
+tst-nodelete-uniquemod.so-no-z-defs = yes
+tst-nodelete-rtldmod.so-no-z-defs = yes
+tst-nodelete-zmod.so-no-z-defs = yes
 
 ifeq ($(build-shared),yes)
 # Build all the modules even when not actually running test programs.
@@ -1153,6 +1158,14 @@ $(objpfx)tst-unique3.out: $(objpfx)tst-unique3lib2.so
 
 $(objpfx)tst-unique4: $(objpfx)tst-unique4lib.so
 
+$(objpfx)tst-nodelete: $(libdl)
+$(objpfx)tst-nodelete.out: $(objpfx)tst-nodelete-uniquemod.so \
+			   $(objpfx)tst-nodelete-rtldmod.so \
+			   $(objpfx)tst-nodelete-zmod.so
+
+LDFLAGS-tst-nodelete = -rdynamic
+LDFLAGS-tst-nodelete-zmod.so = -Wl,--enable-new-dtags,-z,nodelete
+
 $(objpfx)tst-initorder-cmp.out: tst-initorder.exp $(objpfx)tst-initorder.out
 	cmp $^ > $@; \
 	$(evaluate-test)
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 412f71d..2104674 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -108,7 +108,7 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
 
 
 void
-_dl_close_worker (struct link_map *map)
+_dl_close_worker (struct link_map *map, bool force)
 {
   /* One less direct use.  */
   --map->l_direct_opencount;
@@ -152,6 +152,10 @@ _dl_close_worker (struct link_map *map)
       l->l_idx = idx;
       maps[idx] = l;
       ++idx;
+
+      /* Clear DF_1_NODELETE to force object deletion.  */
+      if (force)
+	l->l_flags_1 &= ~DF_1_NODELETE;
     }
   assert (idx == nloaded);
 
@@ -635,6 +639,31 @@ _dl_close_worker (struct link_map *map)
 		}
 	    }
 
+	  /* Reset unique symbols if forced.  */
+	  if (force)
+	    {
+	      struct unique_sym_table *tab = &ns->_ns_unique_sym_table;
+	      __rtld_lock_lock_recursive (tab->lock);
+	      struct unique_sym *entries = tab->entries;
+	      if (entries != NULL)
+		{
+		  size_t idx, size = tab->size;
+		  for (idx = 0; idx < size; ++idx)
+		    {
+		      /* Clear unique symbol entries that belong to this
+			 object.  */
+		      if (entries[idx].name != NULL
+			  && entries[idx].map == imap)
+			{
+			  entries[idx].name = NULL;
+			  entries[idx].hashval = 0;
+			  tab->n_elements--;
+			}
+		    }
+		}
+	      __rtld_lock_unlock_recursive (tab->lock);
+	    }
+
 	  /* We can unmap all the maps at once.  We determined the
 	     start address and length when we loaded the object and
 	     the `munmap' call does the rest.  */
@@ -782,7 +811,7 @@ _dl_close (void *_map)
   /* Acquire the lock.  */
   __rtld_lock_lock_recursive (GL(dl_load_lock));
 
-  _dl_close_worker (map);
+  _dl_close_worker (map, false);
 
   __rtld_lock_unlock_recursive (GL(dl_load_lock));
 }
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 2d0e082..027c1e0 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -670,7 +670,7 @@ no more namespaces available for dlmopen()"));
 	  if ((mode & __RTLD_AUDIT) == 0)
 	    GL(dl_tls_dtv_gaps) = true;
 
-	  _dl_close_worker (args.map);
+	  _dl_close_worker (args.map, true);
 	}
 
       assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
diff --git a/elf/tst-nodelete-rtldmod.cc b/elf/tst-nodelete-rtldmod.cc
new file mode 100644
index 0000000..740e1d8
--- /dev/null
+++ b/elf/tst-nodelete-rtldmod.cc
@@ -0,0 +1,6 @@
+extern int not_exist (void);
+
+int foo (void)
+{
+  return not_exist ();
+}
diff --git a/elf/tst-nodelete-uniquemod.cc b/elf/tst-nodelete-uniquemod.cc
new file mode 100644
index 0000000..632b303
--- /dev/null
+++ b/elf/tst-nodelete-uniquemod.cc
@@ -0,0 +1,14 @@
+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 ();
+}
diff --git a/elf/tst-nodelete-zmod.cc b/elf/tst-nodelete-zmod.cc
new file mode 100644
index 0000000..740e1d8
--- /dev/null
+++ b/elf/tst-nodelete-zmod.cc
@@ -0,0 +1,6 @@
+extern int not_exist (void);
+
+int foo (void)
+{
+  return not_exist ();
+}
diff --git a/elf/tst-nodelete.cc b/elf/tst-nodelete.cc
new file mode 100644
index 0000000..176cb68
--- /dev/null
+++ b/elf/tst-nodelete.cc
@@ -0,0 +1,51 @@
+#include "../dlfcn/dlfcn.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+  int result = 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-nodelete-rtldmod.so", RTLD_NOW | RTLD_NODELETE) != NULL
+      || dlopen ("tst-nodelete-rtldmod.so", RTLD_LAZY | RTLD_NOLOAD) != NULL)
+    {
+      printf ("RTLD_NODELETE test failed\n");
+      result = 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-nodelete-zmod.so", RTLD_NOW) != NULL
+      || dlopen ("tst-nodelete-zmod.so", RTLD_LAZY | RTLD_NOLOAD) != NULL)
+    {
+      printf ("-z nodelete test failed\n");
+      result = 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-nodelete-uniquemod.so", RTLD_NOW) != NULL
+      || dlopen ("tst-nodelete-uniquemod.so", RTLD_LAZY | RTLD_NOLOAD) != NULL)
+    {
+      printf ("Unique symbols test failed\n");
+      result = 1;
+    }
+
+  if (result == 0)
+    printf ("SUCCESS\n");
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/elf/tst-znodelete-zlib.cc b/elf/tst-znodelete-zlib.cc
new file mode 100644
index 0000000..1e8f368
--- /dev/null
+++ b/elf/tst-znodelete-zlib.cc
@@ -0,0 +1,6 @@
+extern int not_exist (void);
+
+int foo (void)
+{
+  return  not_exist ();
+}
diff --git a/include/dlfcn.h b/include/dlfcn.h
index a67b2e3..0ce0af5 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -54,7 +54,8 @@ struct link_map;
 extern void _dl_close (void *map) attribute_hidden;
 /* Same as above, but without locking and safety checks for user
    provided map arguments.  */
-extern void _dl_close_worker (struct link_map *map) attribute_hidden;
+extern void _dl_close_worker (struct link_map *map, bool force)
+    attribute_hidden;
 
 /* Look up NAME in shared object HANDLE (which may be RTLD_DEFAULT or
    RTLD_NEXT).  WHO is the calling function, for RTLD_NEXT.  Returns

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                     |   22 +++++++++++++++++
 NEWS                          |   26 ++++++++++----------
 elf/Makefile                  |   17 ++++++++++++-
 elf/dl-close.c                |   33 +++++++++++++++++++++++++-
 elf/dl-open.c                 |    2 +-
 elf/tst-nodelete-rtldmod.cc   |    6 +++++
 elf/tst-nodelete-uniquemod.cc |   14 +++++++++++
 elf/tst-nodelete-zmod.cc      |    6 +++++
 elf/tst-nodelete.cc           |   51 +++++++++++++++++++++++++++++++++++++++++
 elf/tst-znodelete-zlib.cc     |    6 +++++
 include/dlfcn.h               |    3 +-
 11 files changed, 167 insertions(+), 19 deletions(-)
 create mode 100644 elf/tst-nodelete-rtldmod.cc
 create mode 100644 elf/tst-nodelete-uniquemod.cc
 create mode 100644 elf/tst-nodelete-zmod.cc
 create mode 100644 elf/tst-nodelete.cc
 create mode 100644 elf/tst-znodelete-zlib.cc


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]