Author: Georgii Rymar Date: 2020-12-24T11:16:31+03:00 New Revision: b8cb1802a8a2037bd893e038b4eafa61bd5c279e
URL: https://github.com/llvm/llvm-project/commit/b8cb1802a8a2037bd893e038b4eafa61bd5c279e DIFF: https://github.com/llvm/llvm-project/commit/b8cb1802a8a2037bd893e038b4eafa61bd5c279e.diff LOG: [obj2yaml] - Dump the content of a broken GNU hash table properly. When something is wrong with the GNU hash table header we dump its context as a raw data. Currently we have the calculation overflow issue and it is possible to bypass the validation we have (and crash). The patch fixes it. Differential revision: https://reviews.llvm.org/D93760 Added: Modified: llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: ################################################################################ diff --git a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml index 7dd0a7c870ea..00861c013100 100644 --- a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml +++ b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml @@ -54,9 +54,12 @@ Sections: # INVALID-NEXT: - Name: .gnu.hash.broken.maskwords # INVALID-NEXT: Type: SHT_GNU_HASH # INVALID-NEXT: Content: '00000000000000000100000000000000' -# INVALID-NEXT: - Name: .gnu.hash.broken.nbuckets +# INVALID-NEXT: - Name: .gnu.hash.broken.nbuckets.a # INVALID-NEXT: Type: SHT_GNU_HASH # INVALID-NEXT: Content: '01000000000000000000000000000000' +# INVALID-NEXT: - Name: .gnu.hash.broken.nbuckets.b +# INVALID-NEXT: Type: SHT_GNU_HASH +# INVALID-NEXT: Content: FFFFFFFF000000000100000000000000{{$}} # INVALID-NEXT: - Name: .gnu.hash.hashvalues.ok # INVALID-NEXT: Type: SHT_GNU_HASH # INVALID-NEXT: Header: @@ -108,9 +111,9 @@ Sections: BloomFilter: [] HashBuckets: [] HashValues: [] -## Case 4: NBuckets field is broken, it says that the number of entries +## Case 4(a): NBuckets field is broken, it says that the number of entries ## in the hash buckets is 1, but it is empty. - - Name: .gnu.hash.broken.nbuckets + - Name: .gnu.hash.broken.nbuckets.a Type: SHT_GNU_HASH Header: SymNdx: 0x0 @@ -120,6 +123,18 @@ Sections: BloomFilter: [] HashBuckets: [] HashValues: [] +## Case 4(b): NBuckets = 0xFFFFFFFF is incorrect. The result will cause 32-bit +## unsigned overflows if we keep intermediate expressions uint32_t. + - Name: .gnu.hash.broken.nbuckets.b + Type: SHT_GNU_HASH + Header: + SymNdx: 0x0 + Shift2: 0x0 + MaskWords: 0x1 + NBuckets: 0xFFFFFFFF + BloomFilter: [] + HashBuckets: [] + HashValues: [] ## Case 5: Check that we use the various properties to dump the data when it ## has a size that is a multiple of 4, but fallback to dumping the whole section ## using the "Content" property otherwise. diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 1f9ff88f042a..2b54acd99f9e 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -1271,9 +1271,9 @@ ELFDumper<ELFT>::dumpGnuHashSection(const Elf_Shdr *Shdr) { ELFYAML::GnuHashHeader Header; DataExtractor::Cursor Cur(0); - uint32_t NBuckets = Data.getU32(Cur); + uint64_t NBuckets = Data.getU32(Cur); Header.SymNdx = Data.getU32(Cur); - uint32_t MaskWords = Data.getU32(Cur); + uint64_t MaskWords = Data.getU32(Cur); Header.Shift2 = Data.getU32(Cur); // Set just the raw binary content if we were unable to read the header _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits