Skip to content

Commit 9077974

Browse files
author
George Rimar
committed
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373476 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 60c50e7 commit 9077974

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

test/tools/llvm-readobj/elf-hash-symbols.test

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,3 +361,43 @@ ProgramHeaders:
361361
PAddr: 0x1000
362362
Sections:
363363
- Section: .dynamic
364+
365+
## Show that we report a warning for a hash table which contains an entry of
366+
## the bucket array pointing to a cycle.
367+
368+
# RUN: yaml2obj --docnum=6 %s -o %t6.so
369+
# RUN: llvm-readelf --hash-symbols %t6.so 2>&1 | FileCheck %s -DFILE=%t6.so --check-prefix=BROKEN
370+
371+
# BROKEN: Symbol table of .hash for image:
372+
# BROKEN-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
373+
# BROKEN-NEXT: 1 0: 00000000 0 NOTYPE LOCAL DEFAULT UND aaa
374+
# BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain
375+
376+
--- !ELF
377+
FileHeader:
378+
Class: ELFCLASS32
379+
Data: ELFDATA2LSB
380+
Type: ET_DYN
381+
Machine: EM_386
382+
Sections:
383+
- Name: .hash
384+
Type: SHT_HASH
385+
Link: .dynsym
386+
Bucket: [ 1 ]
387+
Chain: [ 1, 1 ]
388+
- Name: .dynamic
389+
Type: SHT_DYNAMIC
390+
Entries:
391+
## llvm-readelf will read the hash table from the file offset
392+
## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset,
393+
## which is the start of PT_LOAD, i.e. the file offset of .hash.
394+
- Tag: DT_HASH
395+
Value: 0x0
396+
DynamicSymbols:
397+
- Name: aaa
398+
- Name: bbb
399+
ProgramHeaders:
400+
- Type: PT_LOAD
401+
Sections:
402+
- Section: .hash
403+
- Section: .dynamic

tools/llvm-readobj/ELFDumper.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,10 +3437,21 @@ template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) {
34373437
for (uint32_t Buc = 0; Buc < SysVHash->nbucket; Buc++) {
34383438
if (Buckets[Buc] == ELF::STN_UNDEF)
34393439
continue;
3440+
std::vector<bool> Visited(SysVHash->nchain);
34403441
for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash->nchain; Ch = Chains[Ch]) {
34413442
if (Ch == ELF::STN_UNDEF)
34423443
break;
3444+
3445+
if (Visited[Ch]) {
3446+
reportWarning(
3447+
createError(".hash section is invalid: bucket " + Twine(Ch) +
3448+
": a cycle was detected in the linked chain"),
3449+
this->FileName);
3450+
break;
3451+
}
3452+
34433453
printHashedSymbol(Obj, &DynSyms[0], Ch, StringTable, Buc);
3454+
Visited[Ch] = true;
34443455
}
34453456
}
34463457
}

0 commit comments

Comments
 (0)