diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2018-08-25 06:17:52 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-08-25 06:18:06 -0700 |
commit | 7a815dd566f3dd32435ac73aa0a0cc948d525e06 (patch) | |
tree | 56d4e2e6724b24469ee4d1d657bc0a6470be3885 /binutils/readelf.c | |
parent | bbf6c6b8ca19efd7b0c9bf789bbafc1262a27517 (diff) | |
download | binutils-gdb-7a815dd566f3dd32435ac73aa0a0cc948d525e06.tar.gz |
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.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r-- | binutils/readelf.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c index 8d4054fbd26..23e61d369ac 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -11300,6 +11300,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) @@ -11317,6 +11318,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 @@ -11359,6 +11362,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); @@ -11450,6 +11456,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; } |