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.23-534-gb6084a9


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  b6084a958f20b795e5e0a0644d72b6e162334cdf (commit)
      from  2cbec365663cd0e2fe21f77b1f5e20ae3ab5f538 (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=b6084a958f20b795e5e0a0644d72b6e162334cdf

commit b6084a958f20b795e5e0a0644d72b6e162334cdf
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Sat May 7 02:29:54 2016 +0100

    Treat STV_HIDDEN and STV_INTERNAL symbols as STB_LOCAL
    
    In a reference to PR ld/19908 make ld.so respect symbol export classes
    aka visibility and treat STV_HIDDEN and STV_INTERNAL symbols as local,
    preventing such symbols from preempting exported symbols.
    
    According to the ELF gABI[1] neither STV_HIDDEN nor STV_INTERNAL symbols
    are supposed to be present in linked binaries:
    
    "A hidden symbol contained in a relocatable object must be either
    removed or converted to STB_LOCAL binding by the link-editor when the
    relocatable object is included in an executable file or shared object."
    
    "An internal symbol contained in a relocatable object must be either
    removed or converted to STB_LOCAL binding by the link-editor when the
    relocatable object is included in an executable file or shared object."
    
    however some GNU binutils versions produce such symbols in some cases.
    PR ld/19908 is one and we also have this note in scripts/abilist.awk:
    
    so clearly there is linked code out there which contains such symbols
    which is prone to symbol table misinterpretation, and it'll be more
    productive if we handle this gracefully, under the Robustness Principle:
    "be liberal in what you accept, and conservative in what you produce",
    especially as this is a simple (STV_HIDDEN|STV_INTERNAL) => STB_LOCAL
    mapping.
    
    References:
    
    [1] "System V Application Binary Interface - DRAFT - 24 April 2001",
        The Santa Cruz Operation, Inc., "Symbol Table",
        <http://www.sco.com/developers/gabi/2001-04-24/ch4.symtab.html>
    
    	* sysdeps/generic/ldsodefs.h
    	(dl_symbol_visibility_binds_local_p): New inline function.
    	* elf/dl-addr.c (determine_info): Treat hidden and internal
    	symbols as local.
    	* elf/dl-lookup.c (do_lookup_x): Likewise.
    	* elf/dl-reloc.c (RESOLVE_MAP): Likewise.

diff --git a/ChangeLog b/ChangeLog
index a7ca1ff..29a92f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-07-01  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* sysdeps/generic/ldsodefs.h
+	(dl_symbol_visibility_binds_local_p): New inline function.
+	* elf/dl-addr.c (determine_info): Treat hidden and internal
+	symbols as local.
+	* elf/dl-lookup.c (do_lookup_x): Likewise.
+	* elf/dl-reloc.c (RESOLVE_MAP): Likewise.
+
 2016-07-01  Aurelien Jarno  <aurelien@aurel32.net>
 
 	* sparc/sparc32/sparcv9/fpu/s_nearbyint.S (__nearbyint): Trigger an
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index 291ff55..1b16a58 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -88,6 +88,7 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
       for (; (void *) symtab < (void *) symtabend; ++symtab)
 	if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
 	     || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
+	    && __glibc_likely (!dl_symbol_visibility_binds_local_p (symtab))
 	    && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
 	    && (symtab->st_shndx != SHN_UNDEF
 		|| symtab->st_value != 0)
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 6d299c1..52c994e 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -516,6 +516,10 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
 #endif
 	    }
 
+	  /* Hidden and internal symbols are local, ignore them.  */
+	  if (__glibc_unlikely (dl_symbol_visibility_binds_local_p (sym)))
+	    goto skip;
+
 	  switch (ELFW(ST_BIND) (sym->st_info))
 	    {
 	    case STB_WEAK:
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 14709f9..42bddc1 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -233,7 +233,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 
     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 #define RESOLVE_MAP(ref, version, r_type) \
-    (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
+    ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
+      && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref)))	      \
      ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
 	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
 	? (bump_num_cache_relocations (),				      \
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index ddec0be..f68fdf4 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -88,6 +88,19 @@ typedef struct link_map *lookup_t;
        || (ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size)	\
    && ((MATCHSYM) == NULL || (MATCHSYM)->st_value < (SYM)->st_value))
 
+/* According to the ELF gABI no STV_HIDDEN or STV_INTERNAL symbols are
+   expected to be present in dynamic symbol tables as they should have
+   been either removed or converted to STB_LOCAL binding by the static
+   linker.  However some GNU binutils versions produce such symbols in
+   some cases.  To prevent such symbols present in a buggy binary from
+   preempting global symbols we filter them out with this predicate.  */
+static __always_inline bool
+dl_symbol_visibility_binds_local_p (const ElfW(Sym) *sym)
+{
+  return (ELFW(ST_VISIBILITY) (sym->st_other) == STV_HIDDEN
+	  || ELFW(ST_VISIBILITY) (sym->st_other) == STV_INTERNAL);
+}
+
 /* Unmap a loaded object, called by _dl_close (). */
 #ifndef DL_UNMAP_IS_SPECIAL
 # define DL_UNMAP(map)	_dl_unmap_segments (map)

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

Summary of changes:
 ChangeLog                  |    9 +++++++++
 elf/dl-addr.c              |    1 +
 elf/dl-lookup.c            |    4 ++++
 elf/dl-reloc.c             |    3 ++-
 sysdeps/generic/ldsodefs.h |   13 +++++++++++++
 5 files changed, 29 insertions(+), 1 deletions(-)


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]