diff options
author | 2024-10-31 20:08:59 +0000 | |
---|---|---|
committer | 2025-01-28 10:25:44 -0800 | |
commit | 64031cfed5d7e0f372cf5893d88aa73507ad5c63 (patch) | |
tree | c7d3b7b6a1ae268a3be9bb0a1d1c488fc25563b6 /runtime/class_linker.cc | |
parent | 701bd96db052c26b1605066af7f1230b66435638 (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.cc | 25 |
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, |