diff options
| -rw-r--r-- | runtime/hidden_api.h | 74 | ||||
| -rw-r--r-- | runtime/hidden_api_access_flags.h | 18 | ||||
| -rw-r--r-- | runtime/jni_internal.cc | 3 | ||||
| -rw-r--r-- | runtime/native/java_lang_Class.cc | 3 |
4 files changed, 75 insertions, 23 deletions
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h index 05e68e66dd..d7e5e18b9e 100644 --- a/runtime/hidden_api.h +++ b/runtime/hidden_api.h @@ -31,6 +31,23 @@ enum Action { kDeny }; +enum AccessMethod { + kReflection, + kJNI +}; + +inline std::ostream& operator<<(std::ostream& os, AccessMethod value) { + switch (value) { + case kReflection: + os << "reflection"; + break; + case kJNI: + os << "JNI"; + break; + } + return os; +} + inline Action GetMemberAction(uint32_t access_flags) { switch (HiddenApiAccessFlags::DecodeFromRuntime(access_flags)) { case HiddenApiAccessFlags::kWhitelist: @@ -45,19 +62,25 @@ inline Action GetMemberAction(uint32_t access_flags) { } // Issue a warning about field access. -inline void WarnAboutMemberAccess(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_) { +inline void WarnAboutMemberAccess(ArtField* field, AccessMethod access_method) + REQUIRES_SHARED(Locks::mutator_lock_) { std::string tmp; LOG(WARNING) << "Accessing hidden field " << field->GetDeclaringClass()->GetDescriptor(&tmp) << "->" - << field->GetName() << ":" << field->GetTypeDescriptor(); + << field->GetName() << ":" << field->GetTypeDescriptor() + << " (" << HiddenApiAccessFlags::DecodeFromRuntime(field->GetAccessFlags()) + << ", " << access_method << ")"; } // Issue a warning about method access. -inline void WarnAboutMemberAccess(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) { +inline void WarnAboutMemberAccess(ArtMethod* method, AccessMethod access_method) + REQUIRES_SHARED(Locks::mutator_lock_) { std::string tmp; LOG(WARNING) << "Accessing hidden method " << method->GetDeclaringClass()->GetDescriptor(&tmp) << "->" - << method->GetName() << method->GetSignature().ToString(); + << method->GetName() << method->GetSignature().ToString() + << " (" << HiddenApiAccessFlags::DecodeFromRuntime(method->GetAccessFlags()) + << ", " << access_method << ")"; } // Returns true if access to `member` should be denied to the caller of the @@ -69,7 +92,8 @@ inline void WarnAboutMemberAccess(ArtMethod* method) REQUIRES_SHARED(Locks::muta template<typename T> inline bool ShouldBlockAccessToMember(T* member, Thread* self, - std::function<bool(Thread*)> fn_caller_in_boot) + std::function<bool(Thread*)> fn_caller_in_boot, + AccessMethod access_method) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(member != nullptr); Runtime* runtime = Runtime::Current(); @@ -92,25 +116,33 @@ inline bool ShouldBlockAccessToMember(T* member, return false; } - // Member is hidden and we are not in the boot class path. Act accordingly. + // Member is hidden and we are not in the boot class path. + + // Print a log message with information about this class member access. + // We do this regardless of whether we block the access or not. + WarnAboutMemberAccess(member, access_method); + + // Block access if on blacklist. if (action == kDeny) { return true; - } else { - DCHECK(action == kAllowButWarn || action == kAllowButWarnAndToast); - - // Allow access to this member but print a warning. Depending on a runtime - // flag, we might move the member into whitelist and skip the warning the - // next time the member is used. - if (runtime->ShouldDedupeHiddenApiWarnings()) { - member->SetAccessFlags(HiddenApiAccessFlags::EncodeForRuntime( - member->GetAccessFlags(), HiddenApiAccessFlags::kWhitelist)); - } - WarnAboutMemberAccess(member); - if (action == kAllowButWarnAndToast || runtime->ShouldAlwaysSetHiddenApiWarningFlag()) { - Runtime::Current()->SetPendingHiddenApiWarning(true); - } - return false; } + + // Allow access to this member but print a warning. + DCHECK(action == kAllowButWarn || action == kAllowButWarnAndToast); + + // Depending on a runtime flag, we might move the member into whitelist and + // skip the warning the next time the member is accessed. + if (runtime->ShouldDedupeHiddenApiWarnings()) { + member->SetAccessFlags(HiddenApiAccessFlags::EncodeForRuntime( + member->GetAccessFlags(), HiddenApiAccessFlags::kWhitelist)); + } + + // If this action requires a UI warning, set the appropriate flag. + if (action == kAllowButWarnAndToast || runtime->ShouldAlwaysSetHiddenApiWarningFlag()) { + Runtime::Current()->SetPendingHiddenApiWarning(true); + } + + return false; } // Returns true if access to member with `access_flags` should be denied to `caller`. diff --git a/runtime/hidden_api_access_flags.h b/runtime/hidden_api_access_flags.h index c328f965d2..6a88c12be5 100644 --- a/runtime/hidden_api_access_flags.h +++ b/runtime/hidden_api_access_flags.h @@ -146,6 +146,24 @@ class HiddenApiAccessFlags { }; }; +inline std::ostream& operator<<(std::ostream& os, HiddenApiAccessFlags::ApiList value) { + switch (value) { + case HiddenApiAccessFlags::kWhitelist: + os << "whitelist"; + break; + case HiddenApiAccessFlags::kLightGreylist: + os << "light greylist"; + break; + case HiddenApiAccessFlags::kDarkGreylist: + os << "dark greylist"; + break; + case HiddenApiAccessFlags::kBlacklist: + os << "blacklist"; + break; + } + return os; +} + } // namespace art diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index 666fb98354..cd4d9543be 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -90,7 +90,8 @@ static bool IsCallerInBootClassPath(Thread* self) REQUIRES_SHARED(Locks::mutator template<typename T> ALWAYS_INLINE static bool ShouldBlockAccessToMember(T* member, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - return hiddenapi::ShouldBlockAccessToMember(member, self, IsCallerInBootClassPath); + return hiddenapi::ShouldBlockAccessToMember( + member, self, IsCallerInBootClassPath, hiddenapi::kJNI); } // Helpers to call instrumentation functions for fields. These take jobjects so we don't need to set diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 2091a27ffd..4597f68f54 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -97,7 +97,8 @@ ALWAYS_INLINE static bool ShouldEnforceHiddenApi(Thread* self) template<typename T> ALWAYS_INLINE static bool ShouldBlockAccessToMember(T* member, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - return hiddenapi::ShouldBlockAccessToMember(member, self, IsCallerInBootClassPath); + return hiddenapi::ShouldBlockAccessToMember( + member, self, IsCallerInBootClassPath, hiddenapi::kReflection); } // Returns true if a class member should be discoverable with reflection given |