[llvm] r373476 - [llvm-readelf] - Report a warning when .hash section contains a chain with a cycle.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 2 07:11:35 PDT 2019


Author: grimar
Date: Wed Oct  2 07:11:35 2019
New Revision: 373476

URL: http://llvm.org/viewvc/llvm-project?rev=373476&view=rev
Log:
[llvm-readelf] - Report a warning when .hash section contains a chain with a cycle.

It is possible to craft a .hash section that triggers an infinite loop
in llvm-readelf code. This patch fixes the issue and introduces
a warning.

Differential revision: https://reviews.llvm.org/D68086

Modified:
    llvm/trunk/test/tools/llvm-readobj/elf-hash-symbols.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/test/tools/llvm-readobj/elf-hash-symbols.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-hash-symbols.test?rev=373476&r1=373475&r2=373476&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-hash-symbols.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/elf-hash-symbols.test Wed Oct  2 07:11:35 2019
@@ -361,3 +361,43 @@ ProgramHeaders:
     PAddr: 0x1000
     Sections:
       - Section: .dynamic
+
+## Show that we report a warning for a hash table which contains an entry of
+## the bucket array pointing to a cycle.
+
+# RUN: yaml2obj --docnum=6 %s -o %t6.so
+# RUN: llvm-readelf --hash-symbols %t6.so 2>&1 | FileCheck %s -DFILE=%t6.so --check-prefix=BROKEN
+
+# BROKEN:      Symbol table of .hash for image:
+# BROKEN-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
+# BROKEN-NEXT:    1   0: 00000000     0 NOTYPE  LOCAL  DEFAULT UND aaa
+# BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_386
+Sections:
+  - Name:    .hash
+    Type:    SHT_HASH
+    Link:    .dynsym
+    Bucket:  [ 1 ]
+    Chain:   [ 1, 1 ]
+  - Name:  .dynamic
+    Type:  SHT_DYNAMIC
+    Entries:
+## llvm-readelf will read the hash table from the file offset
+## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset,
+## which is the start of PT_LOAD, i.e. the file offset of .hash.
+      - Tag:   DT_HASH
+        Value: 0x0
+DynamicSymbols:
+  - Name:    aaa
+  - Name:    bbb
+ProgramHeaders:
+  - Type:  PT_LOAD
+    Sections:
+      - Section: .hash
+      - Section: .dynamic

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=373476&r1=373475&r2=373476&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Oct  2 07:11:35 2019
@@ -3437,10 +3437,21 @@ template <class ELFT> void GNUStyle<ELFT
     for (uint32_t Buc = 0; Buc < SysVHash->nbucket; Buc++) {
       if (Buckets[Buc] == ELF::STN_UNDEF)
         continue;
+      std::vector<bool> Visited(SysVHash->nchain);
       for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash->nchain; Ch = Chains[Ch]) {
         if (Ch == ELF::STN_UNDEF)
           break;
+
+        if (Visited[Ch]) {
+          reportWarning(
+              createError(".hash section is invalid: bucket " + Twine(Ch) +
+                          ": a cycle was detected in the linked chain"),
+              this->FileName);
+          break;
+        }
+
         printHashedSymbol(Obj, &DynSyms[0], Ch, StringTable, Buc);
+        Visited[Ch] = true;
       }
     }
   }




More information about the llvm-commits mailing list