From 64ee8aeaeb70aa2d5d1c3ff57a682a5001869653 Mon Sep 17 00:00:00 2001 From: Mathew Inwood Date: Mon, 9 Apr 2018 12:24:55 +0100 Subject: Consider whitelist when listing class members. Previously, only the enforcement policy was considered when getting declared fields or members, meaning whitelisted APIs would still not be discoverable. Fix this by calling hiddenapi::GetMemberAction from within IsDiscoverable. Bug: 77787686 Bug: 64382372 Test: cts/tests/signature/runSignatureTests.sh (with ag/3863796) Test: art/test.py --host -t 674-hiddenapi Change-Id: I234d274f47f377e3e105c81aae2d49072287992a --- runtime/native/java_lang_Class.cc | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'runtime/native/java_lang_Class.cc') diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 37724f0f14..a97a17d072 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -125,19 +125,20 @@ ALWAYS_INLINE static bool ShouldBlockAccessToMember(T* member, Thread* self) // the criteria. Some reflection calls only return public members // (public_only == true), some members should be hidden from non-boot class path // callers (enforce_hidden_api == true). +template ALWAYS_INLINE static bool IsDiscoverable(bool public_only, bool enforce_hidden_api, - uint32_t access_flags) { - if (public_only && ((access_flags & kAccPublic) == 0)) { - return false; - } - - if (enforce_hidden_api && - hiddenapi::GetActionFromAccessFlags(access_flags) == hiddenapi::kDeny) { + T* member) + REQUIRES_SHARED(Locks::mutator_lock_) { + if (public_only && ((member->GetAccessFlags() & kAccPublic) == 0)) { return false; } - return true; + return hiddenapi::GetMemberAction(member, + nullptr, + [enforce_hidden_api] (Thread*) { return !enforce_hidden_api; }, + hiddenapi::kNone) + != hiddenapi::kDeny; } ALWAYS_INLINE static inline ObjPtr DecodeClass( @@ -266,12 +267,12 @@ static mirror::ObjectArray* GetDeclaredFields( bool enforce_hidden_api = ShouldEnforceHiddenApi(self); // Lets go subtract all the non discoverable fields. for (ArtField& field : ifields) { - if (!IsDiscoverable(public_only, enforce_hidden_api, field.GetAccessFlags())) { + if (!IsDiscoverable(public_only, enforce_hidden_api, &field)) { --array_size; } } for (ArtField& field : sfields) { - if (!IsDiscoverable(public_only, enforce_hidden_api, field.GetAccessFlags())) { + if (!IsDiscoverable(public_only, enforce_hidden_api, &field)) { --array_size; } } @@ -282,7 +283,7 @@ static mirror::ObjectArray* GetDeclaredFields( return nullptr; } for (ArtField& field : ifields) { - if (IsDiscoverable(public_only, enforce_hidden_api, field.GetAccessFlags())) { + if (IsDiscoverable(public_only, enforce_hidden_api, &field)) { auto* reflect_field = mirror::Field::CreateFromArtField(self, &field, force_resolve); @@ -297,7 +298,7 @@ static mirror::ObjectArray* GetDeclaredFields( } } for (ArtField& field : sfields) { - if (IsDiscoverable(public_only, enforce_hidden_api, field.GetAccessFlags())) { + if (IsDiscoverable(public_only, enforce_hidden_api, &field)) { auto* reflect_field = mirror::Field::CreateFromArtField(self, &field, force_resolve); @@ -518,7 +519,7 @@ static ALWAYS_INLINE inline bool MethodMatchesConstructor( DCHECK(m != nullptr); return m->IsConstructor() && !m->IsStatic() && - IsDiscoverable(public_only, enforce_hidden_api, m->GetAccessFlags()); + IsDiscoverable(public_only, enforce_hidden_api, m); } static jobjectArray Class_getDeclaredConstructorsInternal( @@ -588,7 +589,7 @@ static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaT uint32_t modifiers = m.GetAccessFlags(); // Add non-constructor declared methods. if ((modifiers & kAccConstructor) == 0 && - IsDiscoverable(public_only, enforce_hidden_api, modifiers)) { + IsDiscoverable(public_only, enforce_hidden_api, &m)) { ++num_methods; } } @@ -602,7 +603,7 @@ static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaT for (ArtMethod& m : klass->GetDeclaredMethods(kRuntimePointerSize)) { uint32_t modifiers = m.GetAccessFlags(); if ((modifiers & kAccConstructor) == 0 && - IsDiscoverable(public_only, enforce_hidden_api, modifiers)) { + IsDiscoverable(public_only, enforce_hidden_api, &m)) { DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize); DCHECK(!Runtime::Current()->IsActiveTransaction()); auto* method = -- cgit v1.2.3-59-g8ed1b