diff options
Diffstat (limited to 'runtime/hidden_api.cc')
-rw-r--r-- | runtime/hidden_api.cc | 92 |
1 files changed, 76 insertions, 16 deletions
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc index 3b7b938d50..188c5f353b 100644 --- a/runtime/hidden_api.cc +++ b/runtime/hidden_api.cc @@ -18,8 +18,13 @@ #include <nativehelper/scoped_local_ref.h> +#include "art_field-inl.h" +#include "art_method-inl.h" #include "base/dumpable.h" -#include "thread-current-inl.h" +#include "base/sdk_version.h" +#include "dex/class_accessor-inl.h" +#include "scoped_thread_state_change.h" +#include "thread-inl.h" #include "well_known_classes.h" #ifdef ART_TARGET_ANDROID @@ -71,24 +76,19 @@ enum AccessContextFlags { kAccessDenied = 1 << 1, }; -static int32_t GetMaxAllowedSdkVersionForApiList(ApiList api_list) { - SdkCodes sdk = SdkCodes::kVersionNone; +static SdkVersion GetMaxAllowedSdkVersionForApiList(ApiList api_list) { switch (api_list) { case ApiList::kWhitelist: case ApiList::kLightGreylist: - sdk = SdkCodes::kVersionUnlimited; - break; + return SdkVersion::kMax; case ApiList::kDarkGreylist: - sdk = SdkCodes::kVersionO_MR1; - break; + return SdkVersion::kO_MR1; case ApiList::kBlacklist: - sdk = SdkCodes::kVersionNone; - break; + return SdkVersion::kMin; case ApiList::kNoList: LOG(FATAL) << "Unexpected value"; UNREACHABLE(); } - return static_cast<int32_t>(sdk); } MemberSignature::MemberSignature(ArtField* field) { @@ -235,23 +235,82 @@ void MemberSignature::NotifyHiddenApiListener(AccessMethod access_method) { } } -static ALWAYS_INLINE bool CanUpdateMemberAccessFlags(ArtField*) { +static ALWAYS_INLINE bool CanUpdateRuntimeFlags(ArtField*) { return true; } -static ALWAYS_INLINE bool CanUpdateMemberAccessFlags(ArtMethod* method) { +static ALWAYS_INLINE bool CanUpdateRuntimeFlags(ArtMethod* method) { return !method->IsIntrinsic(); } template<typename T> static ALWAYS_INLINE void MaybeWhitelistMember(Runtime* runtime, T* member) REQUIRES_SHARED(Locks::mutator_lock_) { - if (CanUpdateMemberAccessFlags(member) && runtime->ShouldDedupeHiddenApiWarnings()) { - member->SetAccessFlags(hiddenapi::EncodeForRuntime( - member->GetAccessFlags(), hiddenapi::ApiList::kWhitelist)); + if (CanUpdateRuntimeFlags(member) && runtime->ShouldDedupeHiddenApiWarnings()) { + member->SetAccessFlags(member->GetAccessFlags() | kAccPublicApi); } } +static constexpr uint32_t kNoDexFlags = 0u; +static constexpr uint32_t kInvalidDexFlags = static_cast<uint32_t>(-1); + +uint32_t GetDexFlags(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Class> declaring_class = field->GetDeclaringClass(); + DCHECK(declaring_class != nullptr) << "Fields always have a declaring class"; + + const DexFile::ClassDef* class_def = declaring_class->GetClassDef(); + if (class_def == nullptr) { + return kNoDexFlags; + } + + uint32_t flags = kInvalidDexFlags; + DCHECK(!AreValidFlags(flags)); + + ClassAccessor accessor(declaring_class->GetDexFile(), + *class_def, + /* parse_hiddenapi_class_data= */ true); + auto fn_visit = [&](const ClassAccessor::Field& dex_field) { + if (dex_field.GetIndex() == field->GetDexFieldIndex()) { + flags = dex_field.GetHiddenapiFlags(); + } + }; + accessor.VisitFields(fn_visit, fn_visit); + + CHECK_NE(flags, kInvalidDexFlags) << "Could not find flags for field " << field->PrettyField(); + DCHECK(AreValidFlags(flags)); + return flags; +} + +uint32_t GetDexFlags(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass(); + if (declaring_class.IsNull()) { + DCHECK(method->IsRuntimeMethod()); + return kNoDexFlags; + } + + const DexFile::ClassDef* class_def = declaring_class->GetClassDef(); + if (class_def == nullptr) { + return kNoDexFlags; + } + + uint32_t flags = kInvalidDexFlags; + DCHECK(!AreValidFlags(flags)); + + ClassAccessor accessor(declaring_class->GetDexFile(), + *class_def, + /* parse_hiddenapi_class_data= */ true); + auto fn_visit = [&](const ClassAccessor::Method& dex_method) { + if (dex_method.GetIndex() == method->GetDexMethodIndex()) { + flags = dex_method.GetHiddenapiFlags(); + } + }; + accessor.VisitMethods(fn_visit, fn_visit); + + CHECK_NE(flags, kInvalidDexFlags) << "Could not find flags for method " << method->PrettyMethod(); + DCHECK(AreValidFlags(flags)); + return flags; +} + template<typename T> bool ShouldDenyAccessToMemberImpl(T* member, hiddenapi::ApiList api_list, @@ -263,7 +322,8 @@ bool ShouldDenyAccessToMemberImpl(T* member, const bool deny_access = (policy == EnforcementPolicy::kEnabled) && - (runtime->GetTargetSdkVersion() > GetMaxAllowedSdkVersionForApiList(api_list)); + IsSdkVersionSetAndMoreThan(runtime->GetTargetSdkVersion(), + GetMaxAllowedSdkVersionForApiList(api_list)); MemberSignature member_signature(member); |