Implement VMDebug API to mark a class "platform"
Add a native implementation of VMDebug.allowHiddenApiReflectionFrom
which takes a Class object and sets a new access flag
kAccSkipAccessChecks on the corresponding mirror::Class instance.
The function will throw a SecurityException if the process has not
been forked as Java debuggable.
hiddenapi::IsCallerInPlatformDex is extended to take an optional
argument of the mirror::Class of the caller. If it is set and
the class has kAccSkipAccessChecks, the caller is allowed to
acccess non-SDK APIs.
Note that the mirror::Class of the caller is only provided for
reflection and JNI. The access flag is ignored for other means of
access.
Bug: 64382372
Test: N/A
Change-Id: I2bf0ca7dcb45c17fe91eb2d421c947b892bd6fec
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 2625c0a..68024cd 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -52,7 +52,7 @@
// Returns true if the first caller outside of the Class class or java.lang.invoke package
// is in a platform DEX file.
-static bool IsCallerInPlatformDex(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) {
+static bool IsCallerTrusted(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) {
// Walk the stack and find the first frame not from java.lang.Class and not from java.lang.invoke.
// This is very expensive. Save this till the last.
struct FirstExternalCallerVisitor : public StackVisitor {
@@ -99,7 +99,7 @@
FirstExternalCallerVisitor visitor(self);
visitor.WalkStack();
return visitor.caller != nullptr &&
- hiddenapi::IsCallerInPlatformDex(visitor.caller->GetDeclaringClass());
+ hiddenapi::IsCallerTrusted(visitor.caller->GetDeclaringClass());
}
// Returns true if the first non-ClassClass caller up the stack is not allowed to
@@ -107,7 +107,7 @@
ALWAYS_INLINE static bool ShouldEnforceHiddenApi(Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) {
hiddenapi::EnforcementPolicy policy = Runtime::Current()->GetHiddenApiEnforcementPolicy();
- return policy != hiddenapi::EnforcementPolicy::kNoChecks && !IsCallerInPlatformDex(self);
+ return policy != hiddenapi::EnforcementPolicy::kNoChecks && !IsCallerTrusted(self);
}
// Returns true if the first non-ClassClass caller up the stack should not be
@@ -116,7 +116,7 @@
ALWAYS_INLINE static bool ShouldBlockAccessToMember(T* member, Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) {
hiddenapi::Action action = hiddenapi::GetMemberAction(
- member, self, IsCallerInPlatformDex, hiddenapi::kReflection);
+ member, self, IsCallerTrusted, hiddenapi::kReflection);
if (action != hiddenapi::kAllow) {
hiddenapi::NotifyHiddenApiListener(member);
}