[binutils-gdb/binutils-2_31-branch] elf: Check for corrupt symbol version info

H.J.Lu hjl@sourceware.org
Wed Sep 12 17:48:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=edd27c67f5f4d04331394d295806e697e606bbdb

commit edd27c67f5f4d04331394d295806e697e606bbdb
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Aug 25 06:17:52 2018 -0700

    elf: Check for corrupt symbol version info
    
    The BFD linker with PR ld/23499 may generate shared libraries with
    corrupt symbol version info which leads to linker error when the
    corrupt shared library is used:
    
    /usr/bin/ld: bin/libKF5Service.so.5.49.0: _edata: invalid version 21 (max 0)
    /usr/bin/ld: bin/libKF5Service.so.5.49.0: error adding symbols: bad value
    
    Add check for corrupt symbol version info to objdump:
    
    00000000000af005 g    D  .data	0000000000000000  <corrupt>   _edata
    
    and readelf:
    
       728: 00000000000af005     0 NOTYPE  GLOBAL DEFAULT   25 _edata@<corrupt> (5)
    
    bfd/
    
    	PR ld/23499
    	* elf.c (_bfd_elf_get_symbol_version_string): Return
    	_("<corrupt>") for corrupt symbol version info.
    
    binutils/
    
    	PR ld/23499
    	* readelf.c (get_symbol_version_string): Return _("<corrupt>")
    	for corrupt symbol version info.
    
    (cherry picked from commit 7a815dd566f3dd32435ac73aa0a0cc948d525e06)

Diff:
---
 bfd/ChangeLog      | 6 ++++++
 bfd/elf.c          | 2 +-
 binutils/ChangeLog | 6 ++++++
 binutils/readelf.c | 9 +++++++++
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f0eb899..401b7f1 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,6 +1,12 @@
 2018-09-12  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/23499
+	* elf.c (_bfd_elf_get_symbol_version_string): Return
+	_("<corrupt>") for corrupt symbol version info.
+
+2018-09-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/23499
 	* elflink.c (bfd_elf_record_link_assignment): Always clear
 	h->verinfo.verdef when overriding a dynamic definition.
 
diff --git a/bfd/elf.c b/bfd/elf.c
index 0f75375..8041057 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1877,7 +1877,7 @@ _bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
 	{
 	  Elf_Internal_Verneed *t;
 
-	  version_string = "";
+	  version_string = _("<corrupt>");
 	  for (t = elf_tdata (abfd)->verref;
 	       t != NULL;
 	       t = t->vn_nextref)
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 32f47d5..6ef8592 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/23499
+	* readelf.c (get_symbol_version_string): Return _("<corrupt>")
+	for corrupt symbol version info.
+
 2018-07-18  Nick Clifton  <nickc@redhat.com>
 
 	2.31.1 Release point.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1b50ba7..f4df697 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -11252,6 +11252,7 @@ get_symbol_version_string (Filedata *                   filedata,
   unsigned char data[2];
   unsigned short vers_data;
   unsigned long offset;
+  unsigned short max_vd_ndx;
 
   if (!is_dynsym
       || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
@@ -11269,6 +11270,8 @@ get_symbol_version_string (Filedata *                   filedata,
   if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
     return NULL;
 
+  max_vd_ndx = 0;
+
   /* Usually we'd only see verdef for defined symbols, and verneed for
      undefined symbols.  However, symbols defined by the linker in
      .dynbss for variables copied from a shared library in order to
@@ -11311,6 +11314,9 @@ get_symbol_version_string (Filedata *                   filedata,
 	      ivd.vd_flags = BYTE_GET (evd.vd_flags);
 	    }
 
+	  if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
+	    max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
+
 	  off += ivd.vd_next;
 	}
       while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
@@ -11402,6 +11408,9 @@ get_symbol_version_string (Filedata *                   filedata,
 	  return (ivna.vna_name < strtab_size
 		  ? strtab + ivna.vna_name : _("<corrupt>"));
 	}
+      else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
+	       && (vers_data & VERSYM_VERSION) > max_vd_ndx)
+	return _("<corrupt>");
     }
   return NULL;
 }



More information about the Binutils-cvs mailing list