summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/class_linker.cc25
-rw-r--r--runtime/hidden_api.cc22
-rw-r--r--runtime/hidden_api.h15
-rw-r--r--runtime/hidden_api_test.cc4
-rw-r--r--runtime/jni/jni_internal.cc2
-rw-r--r--runtime/mirror/class-inl.h2
-rw-r--r--runtime/mirror/class.cc2
7 files changed, 46 insertions, 26 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 0ca970aa2d..73c90f58ac 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -5796,7 +5796,7 @@ bool ClassLinker::InitializeClass(Thread* self,
DCHECK(!hiddenapi::ShouldDenyAccessToMember(
field,
hiddenapi::AccessContext(class_loader.Get(), dex_cache.Get()),
- hiddenapi::AccessMethod::kNone));
+ hiddenapi::AccessMethod::kCheckWithPolicy));
dex_cache->SetResolvedField(field_idx, field);
} else {
DCHECK_EQ(field, resolved_field);
@@ -10003,12 +10003,12 @@ ArtMethod* ClassLinker::FindResolvedMethod(ObjPtr<mirror::Class> klass,
}
DCHECK(resolved == nullptr || resolved->GetDeclaringClassUnchecked() != nullptr);
if (resolved != nullptr &&
- // We pass AccessMethod::kNone instead of kLinking to not warn yet on the
+ // We pass AccessMethod::kCheck instead of kLinking to not warn yet on the
// access, as we'll be looking if the method can be accessed through an
// interface.
hiddenapi::ShouldDenyAccessToMember(resolved,
hiddenapi::AccessContext(class_loader, dex_cache),
- hiddenapi::AccessMethod::kNone)) {
+ hiddenapi::AccessMethod::kCheck)) {
// The resolved method that we have found cannot be accessed due to
// hiddenapi (typically it is declared up the hierarchy and is not an SDK
// method). Try to find an interface method from the implemented interfaces which is
@@ -10017,11 +10017,12 @@ ArtMethod* ClassLinker::FindResolvedMethod(ObjPtr<mirror::Class> klass,
if (itf_method == nullptr) {
// No interface method. Call ShouldDenyAccessToMember again but this time
// with AccessMethod::kLinking to ensure that an appropriate warning is
- // logged.
- hiddenapi::ShouldDenyAccessToMember(resolved,
- hiddenapi::AccessContext(class_loader, dex_cache),
- hiddenapi::AccessMethod::kLinking);
- resolved = nullptr;
+ // logged and the enforcement policy is applied.
+ if (hiddenapi::ShouldDenyAccessToMember(resolved,
+ hiddenapi::AccessContext(class_loader, dex_cache),
+ hiddenapi::AccessMethod::kLinking)) {
+ resolved = nullptr;
+ }
} else {
// We found an interface method that is accessible, continue with the resolved method.
}
@@ -10054,10 +10055,10 @@ static bool CheckNoSuchMethod(ArtMethod* method,
ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(dex_cache->GetClassLoader().Ptr() == class_loader.Ptr());
- return method == nullptr ||
- hiddenapi::ShouldDenyAccessToMember(method,
- hiddenapi::AccessContext(class_loader, dex_cache),
- hiddenapi::AccessMethod::kNone); // no warnings
+ return method == nullptr || hiddenapi::ShouldDenyAccessToMember(
+ method,
+ hiddenapi::AccessContext(class_loader, dex_cache),
+ hiddenapi::AccessMethod::kCheckWithPolicy); // no warnings
}
ArtMethod* ClassLinker::FindIncompatibleMethod(ObjPtr<mirror::Class> klass,
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc
index 53010fc0f7..38bd7671e1 100644
--- a/runtime/hidden_api.cc
+++ b/runtime/hidden_api.cc
@@ -70,7 +70,8 @@ static const std::vector<std::string> kWarningExemptions = {
static inline std::ostream& operator<<(std::ostream& os, AccessMethod value) {
switch (value) {
- case AccessMethod::kNone:
+ case AccessMethod::kCheck:
+ case AccessMethod::kCheckWithPolicy:
LOG(FATAL) << "Internal access to hidden API should not be logged";
UNREACHABLE();
case AccessMethod::kReflection:
@@ -394,11 +395,12 @@ void MemberSignature::LogAccessToEventLog(uint32_t sampled_value,
AccessMethod access_method,
bool access_denied) {
#ifdef ART_TARGET_ANDROID
- if (access_method == AccessMethod::kLinking || access_method == AccessMethod::kNone) {
+ if (access_method == AccessMethod::kCheck || access_method == AccessMethod::kCheckWithPolicy ||
+ access_method == AccessMethod::kLinking) {
+ // Checks do not correspond to actual accesses, so should be ignored.
// Linking warnings come from static analysis/compilation of the bytecode
- // and can contain false positives (i.e. code that is never run). We choose
- // not to log these in the event log.
- // None does not correspond to actual access, so should also be ignored.
+ // and can contain false positives (i.e. code that is never run). Hence we
+ // choose to not log those either in the event log.
return;
}
Runtime* runtime = Runtime::Current();
@@ -595,7 +597,13 @@ bool HandleCorePlatformApiViolation(T* member,
DCHECK(policy != EnforcementPolicy::kDisabled)
<< "Should never enter this function when access checks are completely disabled";
- if (access_method != AccessMethod::kNone) {
+ if (access_method == AccessMethod::kCheck) {
+ // Always return true for internal checks, so the current enforcement policy
+ // won't affect the caller.
+ return true;
+ }
+
+ if (access_method != AccessMethod::kCheckWithPolicy) {
LOG(policy == EnforcementPolicy::kEnabled ? ERROR : WARNING)
<< "hiddenapi: Core platform API violation: "
<< Dumpable<MemberSignature>(MemberSignature(member))
@@ -664,7 +672,7 @@ bool ShouldDenyAccessToMemberImpl(T* member,
}
}
- if (access_method != AccessMethod::kNone) {
+ if (access_method != AccessMethod::kCheck && access_method != AccessMethod::kCheckWithPolicy) {
// Warn if blocked signature is being accessed or it is not exempted.
if (deny_access || !member_signature.DoesPrefixMatchAny(kWarningExemptions)) {
// Print a log message with information about this class member access.
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index f503767ed5..9c17f6641d 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -51,9 +51,20 @@ inline EnforcementPolicy EnforcementPolicyFromInt(int api_policy_int) {
}
// Hidden API access method
-// Thist must be kept in sync with VMRuntime.HiddenApiUsageLogger.ACCESS_METHOD_*
+// This must be kept in sync with VMRuntime.HiddenApiUsageLogger.ACCESS_METHOD_*
+// for the access methods that are logged.
enum class AccessMethod {
- kNone = 0, // internal test that does not correspond to an actual access by app
+ // An internal check that does not correspond to an actual access by an app.
+ // It's not logged and the current EnforcementPolicy is not applied. The check
+ // can also be one that, if denied, will be followed by another check with one
+ // of the other methods below (except kCheckWithPolicy), which will then log
+ // and apply the policy (if that one is denied too).
+ kCheck = 0,
+
+ // Like kCheck, except the current EnforcementPolicy is applied (but it still
+ // doesn't log).
+ kCheckWithPolicy = 4,
+
kReflection = 1,
kJNI = 2,
kLinking = 3,
diff --git a/runtime/hidden_api_test.cc b/runtime/hidden_api_test.cc
index 28f1d28c1f..5a2ee55723 100644
--- a/runtime/hidden_api_test.cc
+++ b/runtime/hidden_api_test.cc
@@ -191,7 +191,7 @@ class HiddenApiTest : public CommonRuntimeTest {
// This is only used for log messages, so its state doesn't matter.
const hiddenapi::AccessContext placeholder_context(/* is_trusted= */ false);
- // Choose parameters such that there are no side effects (AccessMethod::kNone)
+ // Choose parameters such that there are no side effects (AccessMethod::kCheck)
// and that the member is not on the exemptions list (here we choose one which
// is not even in boot class path).
return ShouldDenyAccessToMemberImpl(/* member= */ class1_field1_,
@@ -199,7 +199,7 @@ class HiddenApiTest : public CommonRuntimeTest {
/* runtime_flags= */ 0,
/* caller_context= */ placeholder_context,
/* callee_context= */ placeholder_context,
- /* access_method= */ hiddenapi::AccessMethod::kNone);
+ hiddenapi::AccessMethod::kCheck);
}
void TestLocation(const std::string& location, hiddenapi::Domain expected_domain) {
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index f1ea88da4e..588c2cd04d 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -494,7 +494,7 @@ ArtMethod* FindMethodJNI(const ScopedObjectAccess& soa,
method = c->FindClassMethod(name, sig, pointer_size);
}
if (method != nullptr &&
- ShouldDenyAccessToMember(method, soa.Self(), hiddenapi::AccessMethod::kNone)) {
+ ShouldDenyAccessToMember(method, soa.Self(), hiddenapi::AccessMethod::kCheckWithPolicy)) {
// The resolved method that we have found cannot be accessed due to
// hiddenapi (typically it is declared up the hierarchy and is not an SDK
// method). Try to find an interface method from the implemented interfaces which is
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 82e1462add..40f119e3c4 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -422,7 +422,7 @@ inline bool Class::IsDiscoverable(bool public_only,
}
return !hiddenapi::ShouldDenyAccessToMember(
- member, access_context, hiddenapi::AccessMethod::kNone);
+ member, access_context, hiddenapi::AccessMethod::kCheckWithPolicy);
}
// Determine whether "this" is assignable from "src", where both of these
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 327d2b78f1..a6d760a188 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -1962,7 +1962,7 @@ ObjPtr<Method> Class::GetDeclaredMethodInternal(
}
auto h_args = hs.NewHandle(args);
Handle<Class> h_klass = hs.NewHandle(klass);
- constexpr hiddenapi::AccessMethod access_method = hiddenapi::AccessMethod::kNone;
+ constexpr hiddenapi::AccessMethod access_method = hiddenapi::AccessMethod::kCheckWithPolicy;
ArtMethod* result = nullptr;
bool result_hidden = false;
for (auto& m : h_klass->GetDeclaredVirtualMethods(kPointerSize)) {