summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-07-30 18:59:05 -0700
committerAndreas Gampe <agampe@google.com>2014-07-30 20:38:55 -0700
commitaa910d5ef43256102809e397de305c23f1c315e6 (patch)
treeffd2bae0a66e2f174fabc4e8c1062038e5b5dccc /runtime
parentda4a1264cd7d5db9ed01cfd1eeaed71cb11c6c71 (diff)
downloadart-aa910d5ef43256102809e397de305c23f1c315e6.zip
art-aa910d5ef43256102809e397de305c23f1c315e6.tar.gz
art-aa910d5ef43256102809e397de305c23f1c315e6.tar.bz2
ART: Fix verifier mishandling erroneous array component types
The verifier must not assume that component types are not erroneous. Bug: 16661259 Change-Id: I23b2f517259ca9c0b8a1aa38f6348fcd61e0b22e
Diffstat (limited to 'runtime')
-rw-r--r--runtime/mirror/dex_cache-inl.h8
-rw-r--r--runtime/mirror/dex_cache.h7
-rw-r--r--runtime/verifier/reg_type_cache.cc39
-rw-r--r--runtime/verifier/reg_type_cache.h2
4 files changed, 37 insertions, 19 deletions
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index 08cff99..d3fcb55 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -19,6 +19,8 @@
#include "dex_cache.h"
+#include "base/logging.h"
+#include "mirror/class.h"
#include "runtime.h"
namespace art {
@@ -41,6 +43,12 @@ inline ArtMethod* DexCache::GetResolvedMethod(uint32_t method_idx)
}
}
+inline void DexCache::SetResolvedType(uint32_t type_idx, Class* resolved) {
+ // TODO default transaction support.
+ DCHECK(resolved == nullptr || !resolved->IsErroneous());
+ GetResolvedTypes()->Set(type_idx, resolved);
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index bfd603a..2c5fbcd 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -103,11 +103,8 @@ class MANAGED DexCache FINAL : public Object {
return GetResolvedTypes()->Get(type_idx);
}
- void SetResolvedType(uint32_t type_idx, Class* resolved) ALWAYS_INLINE
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // TODO default transaction support.
- GetResolvedTypes()->Set(type_idx, resolved);
- }
+ void SetResolvedType(uint32_t type_idx, Class* resolved)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
ArtMethod* GetResolvedMethod(uint32_t method_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 91fba4d..d51374b 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -185,7 +185,7 @@ const RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descr
} else {
entry = new ReferenceType(klass, descriptor, entries_.size());
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
} else { // Class not resolved.
// We tried loading the class and failed, this might get an exception raised
@@ -198,7 +198,7 @@ const RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descr
}
if (IsValidDescriptor(descriptor)) {
RegType* entry = new UnresolvedReferenceType(descriptor, entries_.size());
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
} else {
// The descriptor is broken return the unknown type as there's nothing sensible that
@@ -209,7 +209,7 @@ const RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descr
}
const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) {
- DCHECK(klass != nullptr);
+ DCHECK(klass != nullptr && !klass->IsErroneous());
if (klass->IsPrimitive()) {
// Note: precise isn't used for primitive classes. A char is assignable to an int. All
// primitive classes are final.
@@ -229,7 +229,7 @@ const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* kl
} else {
entry = new ReferenceType(klass, descriptor, entries_.size());
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
}
@@ -339,7 +339,7 @@ const RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegT
}
// Create entry.
RegType* entry = new UnresolvedMergedType(left.GetId(), right.GetId(), this, entries_.size());
- entries_.push_back(entry);
+ AddEntry(entry);
if (kIsDebugBuild) {
UnresolvedMergedType* tmp_entry = down_cast<UnresolvedMergedType*>(entry);
std::set<uint16_t> check_types = tmp_entry->GetMergedTypes();
@@ -363,7 +363,7 @@ const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) {
}
}
RegType* entry = new UnresolvedSuperClass(child.GetId(), this, entries_.size());
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
@@ -393,7 +393,7 @@ const UninitializedType& RegTypeCache::Uninitialized(const RegType& type, uint32
}
entry = new UninitializedReferenceType(klass, descriptor, allocation_pc, entries_.size());
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
@@ -435,7 +435,7 @@ const RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) {
return Conflict();
}
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
@@ -498,7 +498,7 @@ const UninitializedType& RegTypeCache::UninitializedThisArgument(const RegType&
}
entry = new UninitializedThisReferenceType(klass, descriptor, entries_.size());
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
@@ -517,7 +517,7 @@ const ConstantType& RegTypeCache::FromCat1NonSmallConstant(int32_t value, bool p
} else {
entry = new ImpreciseConstType(value, entries_.size());
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
@@ -535,7 +535,7 @@ const ConstantType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
} else {
entry = new ImpreciseConstLoType(value, entries_.size());
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
@@ -553,7 +553,7 @@ const ConstantType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
} else {
entry = new ImpreciseConstHiType(value, entries_.size());
}
- entries_.push_back(entry);
+ AddEntry(entry);
return *entry;
}
@@ -566,8 +566,15 @@ const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::Clas
return FromDescriptor(loader, component.c_str(), false);
} else {
mirror::Class* klass = array.GetClass()->GetComponentType();
- return FromClass(klass->GetDescriptor().c_str(), klass,
- klass->CannotBeAssignedFromOtherTypes());
+ if (klass->IsErroneous()) {
+ // Arrays may have erroneous component types, use unresolved in that case.
+ // We assume that the primitive classes are not erroneous, so we know it is a
+ // reference type.
+ return FromDescriptor(loader, klass->GetDescriptor().c_str(), false);
+ } else {
+ return FromClass(klass->GetDescriptor().c_str(), klass,
+ klass->CannotBeAssignedFromOtherTypes());
+ }
}
}
@@ -586,5 +593,9 @@ void RegTypeCache::VisitRoots(RootCallback* callback, void* arg) {
}
}
+void RegTypeCache::AddEntry(RegType* new_entry) {
+ entries_.push_back(new_entry);
+}
+
} // namespace verifier
} // namespace art
diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h
index 70d5f07..f42fdd1 100644
--- a/runtime/verifier/reg_type_cache.h
+++ b/runtime/verifier/reg_type_cache.h
@@ -154,6 +154,8 @@ class RegTypeCache {
const ConstantType& FromCat1NonSmallConstant(int32_t value, bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void AddEntry(RegType* new_entry);
+
template <class Type>
static Type* CreatePrimitiveTypeInstance(const std::string& descriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);