summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Martin Stjernholm <mast@google.com> 2024-10-31 20:08:59 +0000
committer Martin Stjernholm <mast@google.com> 2025-01-28 10:25:44 -0800
commit64031cfed5d7e0f372cf5893d88aa73507ad5c63 (patch)
treec7d3b7b6a1ae268a3be9bb0a1d1c488fc25563b6 /runtime/class_linker.cc
parent701bd96db052c26b1605066af7f1230b66435638 (diff)
Fix missing logging of core platform API violations in just-warn mode.
In one case a hiddenapi access check was done with hiddenapi::AccessMethod::kNone for an app access, with the intention of following it up with another "real" check that does log and applies the enforcement policy. However, hiddenapi::AccessMethod::kNone applied the current enforcement policy, so the second check would always get skipped if the policy isn't hiddenapi::EnforcementPolicy::kEnabled. That's a problem when it's kJustWarn, because the first check won't log, and the second - which would - is skipped. Fix that by returning an access failure for the first check, regardless of the policy, so that the second doesn't get skipped. The behaviour doesn't change if the policy is kEnabled, and the second check won't do anything if it's kDisabled, so this change only has effect when it's kJustWarn. Also rename kNone to the more apt kCheck. For compatibility in other places where access checks with kNone aren't used like above, introduce a new access method kCheckWithPolicy, which keeps the behaviour of kNone (but with a more descriptive name). Some of those code paths should perhaps be changed to kCheck as well, but that's for another time. Test: Boot and check logcat with planted API violations in system_server. Test: 674-hiddenapi 690-hiddenapi-same-name-methods 691-hiddenapi-proxy 817-hiddenapi 822-hiddenapi-future 999-redefine-hiddenapi 2038-hiddenapi-jvmti-ext 2270-mh-internal-hiddenapi-use on host and target Bug: 377676642 Change-Id: I4ca70c229bd6261a78dcd68990708a318b0e7588
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc25
1 files changed, 13 insertions, 12 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,