ART: Fix dex file verifier type-list handling
It is rare, but valid, to have an empty type list.
Bug: 17327877
(cherry picked from commit 277a7c7b4bb9c421380592fd3998d2e79e4035b3)
Change-Id: Ib3a8ff3e5ccd8fe7c04b1e97485bf3e6de72aa4d
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 1e86bfc..9d3df1d 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -224,6 +224,16 @@
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
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 7e6bdfa..0782045 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -1117,14 +1117,19 @@
}
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: {