OSDN Git Service

ART: Fix dex file verifier type-list handling
authorAndreas Gampe <agampe@google.com>
Fri, 29 Aug 2014 23:07:49 +0000 (16:07 -0700)
committerAndreas Gampe <agampe@google.com>
Sat, 30 Aug 2014 05:16:32 +0000 (22:16 -0700)
It is rare, but valid, to have an empty type list.

Bug: 17327877
Change-Id: Ib3a8ff3e5ccd8fe7c04b1e97485bf3e6de72aa4d

runtime/dex_file.h
runtime/dex_file_verifier.cc

index 2794af6..a71a5e1 100644 (file)
@@ -224,6 +224,16 @@ class DexFile {
       return this->list_[idx];
     }
 
+    // Size in bytes of the part of the list that is common.
+    static constexpr size_t GetHeaderSize() {
+      return 4U;
+    }
+
+    // Size in bytes of the whole type list including all the stored elements.
+    static constexpr size_t GetListSize(size_t count) {
+      return GetHeaderSize() + sizeof(TypeItem) * count;
+    }
+
    private:
     uint32_t size_;  // size of the list, in entries
     TypeItem list_[1];  // elements of the list
index 7e6bdfa..0782045 100644 (file)
@@ -1117,14 +1117,19 @@ bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t count, ui
       }
       case DexFile::kDexTypeTypeList: {
         const DexFile::TypeList* list = reinterpret_cast<const DexFile::TypeList*>(ptr_);
-        const DexFile::TypeItem* item = &list->GetTypeItem(0);
-        uint32_t count = list->Size();
 
-        if (!CheckListSize(list, 1, sizeof(DexFile::TypeList), "type_list") ||
-            !CheckListSize(item, count, sizeof(DexFile::TypeItem), "type_list size")) {
+        // Check that at least the header (size) is available.
+        if (!CheckListSize(list, 1, DexFile::TypeList::GetHeaderSize(), "type_list")) {
           return false;
         }
-        ptr_ = reinterpret_cast<const byte*>(item + count);
+
+        // Check that the whole list is available.
+        const size_t list_size = DexFile::TypeList::GetListSize(list->Size());
+        if (!CheckListSize(list, 1, list_size, "type_list size")) {
+          return false;
+        }
+
+        ptr_ += count;
         break;
       }
       case DexFile::kDexTypeAnnotationSetRefList: {