summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/dex_file.h10
-rw-r--r--runtime/dex_file_verifier.cc15
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: {