]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf: Break sysv[64] symbol hash bucket chain loops.
authorMark Wielaard <mark@klomp.org>
Wed, 28 Mar 2018 19:27:48 +0000 (21:27 +0200)
committerMark Wielaard <mark@klomp.org>
Fri, 30 Mar 2018 20:42:44 +0000 (22:42 +0200)
The bucket chain should not contain loops. If it does we should mark the
hash bucket chain as invalid. This is easily checked by noticing when we
have seen more than the number of chain elements. Which equals the max
number as symbols in the table.

https://sourceware.org/bugzilla/show_bug.cgi?id=23011

Signed-off-by: Mark Wielaard <mark@klomp.org>
src/ChangeLog
src/readelf.c

index 1ad6b3db38e15947791806dcddde6fb8ea1afc79..e8bd6bf1fda17b1588c61fc49cc463893822728e 100644 (file)
@@ -1,3 +1,9 @@
+2018-03-28  Mark Wielaard  <mark@klomp.org>
+
+       * readelf.c (handle_sysv_hash): Break bucket chain after nchain
+       entries are found.
+       (handle_sysv_hash64): Likewise.
+
 2018-03-27  Mark Wielaard  <mark@klomp.org>
 
        * readelf.c (attr_callback): Print dwarf_dieoffset as %PRIx64,
index 4e35b612892a0611966671800c278ab89e175a18..226b19bee60d01d94115a032086be54d4da0ee42 100644 (file)
@@ -3141,9 +3141,13 @@ handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
     {
       Elf32_Word inner = bucket[cnt];
+      Elf32_Word chain_len = 0;
       while (inner > 0 && inner < nchain)
        {
          ++nsyms;
+         ++chain_len;
+         if (chain_len > nchain)
+           goto invalid_data;
          if (maxlength < ++lengths[cnt])
            ++maxlength;
 
@@ -3198,9 +3202,13 @@ handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
   for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
     {
       Elf64_Xword inner = bucket[cnt];
+      Elf64_Xword chain_len = 0;
       while (inner > 0 && inner < nchain)
        {
          ++nsyms;
+         ++chain_len;
+         if (chain_len > nchain)
+           goto invalid_data;
          if (maxlength < ++lengths[cnt])
            ++maxlength;