[PATCH] D93760: [obj2yaml] - Dump the content of a broken GNU hash table properly.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 23 05:25:28 PST 2020


grimar created this revision.
grimar added reviewers: jhenderson, MaskRay.
Herald added a subscriber: emaste.
Herald added a reviewer: espindola.
grimar requested review of this revision.
Herald added a project: LLVM.

When something is wrong with the GNU hash table header we dump
its context as a raw data.

Currently we have an calculation overflow issue and it is possible to
bypass the validation we have.

The patch fixes it.


https://reviews.llvm.org/D93760

Files:
  llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml
  llvm/tools/obj2yaml/elf2yaml.cpp


Index: llvm/tools/obj2yaml/elf2yaml.cpp
===================================================================
--- llvm/tools/obj2yaml/elf2yaml.cpp
+++ llvm/tools/obj2yaml/elf2yaml.cpp
@@ -1271,9 +1271,9 @@
 
   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
Index: llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml
===================================================================
--- llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml
+++ llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml
@@ -54,9 +54,12 @@
 # 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 @@
     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,22 @@
     BloomFilter: []
     HashBuckets: []
     HashValues:  []
+## Case 4(b): the NBuckets field is broken, it says that the number of entries
+## in the hash buckets is 0xFFFFFFFF. In this specific case the following
+## expression overflows the 32-bit unsigned integer type:
+## MaskWords (1) * AddrSize (8) + NBuckets (0xFFFFFFFF) * Word size (4) == 0 (32 bit).
+## The 32-bit result is not greater than the size of the data left after
+## reading the first 8 bytes (MaskWords + MaskWords).
+  - 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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D93760.313539.patch
Type: text/x-patch
Size: 2912 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201223/7c5a2ea1/attachment.bin>


More information about the llvm-commits mailing list