diff options
author | Vladimir Marko <vmarko@google.com> | 2014-01-31 15:03:55 +0000 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2014-02-03 18:15:13 +0000 |
commit | 89786437f4c0176b35ca0376153dd18ab7df4924 (patch) | |
tree | c1b233f9e036c14f7a39d722a7a34874253307c1 /runtime/mirror/class-inl.h | |
parent | 1f00671edaaa34578319d0fdaf605600ed539d41 (diff) | |
download | android_art-89786437f4c0176b35ca0376153dd18ab7df4924.tar.gz android_art-89786437f4c0176b35ca0376153dd18ab7df4924.tar.bz2 android_art-89786437f4c0176b35ca0376153dd18ab7df4924.zip |
Don't assume resolved type has the same dex cache.
When we resolve a type with a certain DexCache that type's
GetDexCache() doesn't necessarily return the same DexCache.
This could have led to the wrong DexFile being used in
access checks by the CompilerDriver.
Change-Id: I2c836477f69f142bcbff902207dc0ad83854a398
Diffstat (limited to 'runtime/mirror/class-inl.h')
-rw-r--r-- | runtime/mirror/class-inl.h | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index cd44ebcb65..8aa833393c 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -203,14 +203,15 @@ inline bool Class::IsAssignableFromArray(const Class* src) const { return IsArrayAssignableFromArray(src); } -template <bool throw_on_failure> -inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field, - uint32_t field_idx) { +template <bool throw_on_failure, bool use_referrers_cache> +inline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field, + uint32_t field_idx, DexCache* dex_cache) { + DCHECK_EQ(use_referrers_cache, dex_cache == nullptr); if (UNLIKELY(!this->CanAccess(access_to))) { // The referrer class can't access the field's declaring class but may still be able // to access the field if the FieldId specifies an accessible subclass of the declaring // class rather than the declaring class itself. - DexCache* referrer_dex_cache = this->GetDexCache(); + DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_; // The referenced class has already been resolved with the field, get it from the dex cache. Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx); @@ -233,15 +234,16 @@ inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field, return false; } -template <bool throw_on_failure, InvokeType throw_invoke_type> -inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method, - uint32_t method_idx) { +template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type> +inline bool Class::ResolvedMethodAccessTest(Class* access_to, ArtMethod* method, + uint32_t method_idx, DexCache* dex_cache) { COMPILE_ASSERT(throw_on_failure || throw_invoke_type == kStatic, non_default_throw_invoke_type); + DCHECK_EQ(use_referrers_cache, dex_cache == nullptr); if (UNLIKELY(!this->CanAccess(access_to))) { // The referrer class can't access the method's declaring class but may still be able // to access the method if the MethodId specifies an accessible subclass of the declaring // class rather than the declaring class itself. - DexCache* referrer_dex_cache = this->GetDexCache(); + DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; // The referenced class has already been resolved with the method, get it from the dex cache. Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx); @@ -265,6 +267,28 @@ inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method, return false; } +inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field, + DexCache& dex_cache, uint32_t field_idx) { + return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, &dex_cache); +} + +inline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field, + uint32_t field_idx) { + return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr); +} + +inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method, + DexCache& dex_cache, uint32_t method_idx) { + return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, &dex_cache); +} + +template <InvokeType throw_invoke_type> +inline bool Class::CheckResolvedMethodAccess(Class* access_to, ArtMethod* method, + uint32_t method_idx) { + return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to, method, method_idx, + nullptr); +} + inline bool Class::IsSubClass(const Class* klass) const { DCHECK(!IsInterface()) << PrettyClass(this); DCHECK(!IsArrayClass()) << PrettyClass(this); |