]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
elf: Check for corrupt symbol version info
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 25 Aug 2018 13:17:52 +0000 (06:17 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 12 Sep 2018 17:01:45 +0000 (10:01 -0700)
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)

bfd/ChangeLog
bfd/elf.c
binutils/ChangeLog
binutils/readelf.c

index f0eb899b264d8bb37741a8f8d229e3b48c1b2558..401b7f13396f58a17b9d3eddb2764fffc3988cdd 100644 (file)
@@ -1,3 +1,9 @@
+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
index 0f753751284ded1f030deac228d53cf067db7740..80410575b09b0476c00c5e592963e4020dd7259a 100644 (file)
--- 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)
index 32f47d5e0701ec0901d11cedcf6cbd8f853a54b6..6ef8592ff26cc849d36d6c2417c5dd825ac5b6bb 100644 (file)
@@ -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.
index 1b50ba763137149a9d1e83d5e0baaf93f6cf2788..f4df697a7de5b950c7df468eed0de64c67602165 100644 (file)
@@ -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;
 }