diff options
| author | George Rimar <grimar@accesssoftek.com> | 2019-10-02 14:11:35 +0000 | 
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2019-10-02 14:11:35 +0000 | 
| commit | 4496f07497a883e44477b0d8f4e331cd030ffd6e (patch) | |
| tree | 690ae172b0cd9c6c8eaca4c8e6cb3bdbf670e7c7 | |
| parent | ed3b68e0dc3c038261bfa591e5223e7f9d1d8b8f (diff) | |
| download | bcm5719-llvm-4496f07497a883e44477b0d8f4e331cd030ffd6e.tar.gz bcm5719-llvm-4496f07497a883e44477b0d8f4e331cd030ffd6e.zip  | |
[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
llvm-svn: 373476
| -rw-r--r-- | llvm/test/tools/llvm-readobj/elf-hash-symbols.test | 40 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 11 | 
2 files changed, 51 insertions, 0 deletions
diff --git a/llvm/test/tools/llvm-readobj/elf-hash-symbols.test b/llvm/test/tools/llvm-readobj/elf-hash-symbols.test index b0140a2e9c1..4ffecf9fcc6 100644 --- a/llvm/test/tools/llvm-readobj/elf-hash-symbols.test +++ b/llvm/test/tools/llvm-readobj/elf-hash-symbols.test @@ -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 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index af3d0e967d1..1b3e8f4851d 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3437,10 +3437,21 @@ template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) {      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;        }      }    }  | 

