From: Georgii Rymar Date: Mon, 23 Nov 2020 08:53:40 +0000 (+0300) Subject: [llvm-readelf/obj] - Fix the possible crash when dumping group sections. X-Git-Tag: llvmorg-13-init~5378 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=76a626b2061bc8a33656a49ebcabbfa75c317d4c;p=platform%2Fupstream%2Fllvm.git [llvm-readelf/obj] - Fix the possible crash when dumping group sections. It is possible to trigger a crash/misbehavior when the st_name field of the signature symbol goes past the end of the string table. This patch fixes it. Differential revision: https://reviews.llvm.org/D91943 --- diff --git a/llvm/test/tools/llvm-readobj/ELF/groups.test b/llvm/test/tools/llvm-readobj/ELF/groups.test index 0069647..afdc63e 100644 --- a/llvm/test/tools/llvm-readobj/ELF/groups.test +++ b/llvm/test/tools/llvm-readobj/ELF/groups.test @@ -81,11 +81,16 @@ Sections: - Name: .symtab Type: SHT_SYMTAB Link: [[SYMTABLINK=.strtab]] + - Name: .strtab + Type: SHT_STRTAB + Content: [[STRTABCONTENT=]] Symbols: - Name: foo Section: .text.foo + StName: [[SYM1STNAME=]] - Name: bar Section: .text.bar + StName: [[SYM2STNAME=]] ## Check that we report a warning and continue dumping when a section is included ## in two group sections at the same time. @@ -379,3 +384,37 @@ Symbols: # MEMBER-GNU-NEXT: [Index] Name # MEMBER-GNU-NEXT: [ 255] # MEMBER-GNU-NEXT: [ 6] .rela.text.bar + +## Check warnings that are reported when the st_name field of the signature symbol goes past the end of the string table. + +## We set the content of the string table to '0061626300' ('\0abc\0') to fixup the size of the string table. +## This makes it easier to test the boundary conditions. +# RUN: yaml2obj %s -DSTRTABCONTENT="0061626300" -DSYM1STNAME=4 -DSYM2STNAME=5 -o %t.signame.o +# RUN: llvm-readobj --elf-section-groups %t.signame.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame.o %s --check-prefixes=SIGNAME1-WARN,SIGNAME1-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf --elf-section-groups %t.signame.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame.o %s --check-prefixes=SIGNAME1-WARN,SIGNAME1-GNU --implicit-check-not=warning: + +# SIGNAME1-WARN: warning: '[[FILE]]': unable to get the name of the symbol with index 2: st_name (0x5) is past the end of the string table of size 0x5 + +# SIGNAME1-LLVM: Signature: {{$}} +# SIGNAME1-LLVM: Signature: + +# SIGNAME1-GNU: COMDAT group section [ 1] `.group' [] contains 2 sections: +# SIGNAME1-GNU: COMDAT group section [ 2] `.group1' [] contains 2 sections: + +## Chech we report a warning when the string table that contains the signature symbol name is not null-terminated. + +# RUN: yaml2obj %s -DSTRTABCONTENT="0061626361" -DSYM1STNAME=4 -DSYM2STNAME=5 -o %t.signame2.o +# RUN: llvm-readobj --elf-section-groups %t.signame2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame2.o %s --check-prefixes=SIGNAME2-WARN,SIGNAME2-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf --elf-section-groups %t.signame2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame2.o %s --check-prefixes=SIGNAME2-WARN,SIGNAME2-GNU --implicit-check-not=warning: + +# SIGNAME2-WARN: warning: '[[FILE]]': unable to get the string table for SHT_SYMTAB section with index 7: SHT_STRTAB string table section [index 8] is non-null terminated + +# SIGNAME2-LLVM: Signature: +# SIGNAME2-LLVM: Signature: + +# SIGNAME2-GNU: COMDAT group section [ 1] `.group' [] contains 2 sections: +# SIGNAME2-GNU: COMDAT group section [ 2] `.group1' [] contains 2 sections: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 3e54c35..c5eb2d6 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3595,7 +3595,7 @@ static StringRef tryGetSectionName(const ELFFile &Obj, } template std::vector DumpStyle::getGroups() { - auto GetSignature = [&](const Elf_Sym &Sym, + auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx, const Elf_Shdr &Symtab) -> StringRef { Expected StrTableOrErr = Obj.getStringTableForSymtab(Symtab); if (!StrTableOrErr) { @@ -3605,8 +3605,16 @@ template std::vector DumpStyle::getGroups() { return ""; } - // TODO: this might lead to a crash or produce a wrong result, when the - // st_name goes past the end of the string table. + StringRef Strings = *StrTableOrErr; + if (Sym.st_name >= Strings.size()) { + reportUniqueWarning(createError( + "unable to get the name of the symbol with index " + Twine(SymNdx) + + ": st_name (0x" + Twine::utohexstr(Sym.st_name) + + ") is past the end of the string table of size 0x" + + Twine::utohexstr(Strings.size()))); + return ""; + } + return StrTableOrErr->data() + Sym.st_name; }; @@ -3621,7 +3629,7 @@ template std::vector DumpStyle::getGroups() { if (Expected SymtabOrErr = Obj.getSection(Sec.sh_link)) { if (Expected SymOrErr = Obj.template getEntry(**SymtabOrErr, Sec.sh_info)) - Signature = GetSignature(**SymOrErr, **SymtabOrErr); + Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr); else reportUniqueWarning(createError( "unable to get the signature symbol for " + describe(Obj, Sec) +