diff options
| -rw-r--r-- | runtime/dex_file.h | 10 | ||||
| -rw-r--r-- | runtime/dex_file_verifier.cc | 15 |
2 files changed, 20 insertions, 5 deletions
diff --git a/runtime/dex_file.h b/runtime/dex_file.h index 1e86bfcf4f..9d3df1d9e3 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -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 diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc index 7e6bdfa4d4..078204518a 100644 --- a/runtime/dex_file_verifier.cc +++ b/runtime/dex_file_verifier.cc @@ -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: { |