ART: Check for duplicate class definitions in dex file verifier

Reject dex files that try to define two classes with the same type id.

Bug: 16016492
Change-Id: I82cc99c00b3e3cb2b3d537ec14beed9049fe900f
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 48dcdca..7e6bdfa 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -1655,6 +1655,13 @@
 bool DexFileVerifier::CheckInterClassDefItem() {
   const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_);
 
+  // Check for duplicate class def.
+  if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) {
+    ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_);
+    return false;
+  }
+  defined_classes_.insert(item->class_idx_);
+
   LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_class_def_item class_idx")
   if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
     ErrorStringPrintf("Invalid class descriptor: '%s'", class_descriptor);
diff --git a/runtime/dex_file_verifier.h b/runtime/dex_file_verifier.h
index cae1063..0af3549 100644
--- a/runtime/dex_file_verifier.h
+++ b/runtime/dex_file_verifier.h
@@ -17,6 +17,8 @@
 #ifndef ART_RUNTIME_DEX_FILE_VERIFIER_H_
 #define ART_RUNTIME_DEX_FILE_VERIFIER_H_
 
+#include <unordered_set>
+
 #include "dex_file.h"
 #include "safe_map.h"
 
@@ -114,6 +116,9 @@
   const void* previous_item_;
 
   std::string failure_reason_;
+
+  // Set of type ids for which there are ClassDef elements in the dex file.
+  std::unordered_set<decltype(DexFile::ClassDef::class_idx_)> defined_classes_;
 };
 
 }  // namespace art