blob: 66e81c4d53bacd23de12ccb0eeaef37e69032e08 [file] [log] [blame]
David Brazdil5a61bb72018-01-19 16:59:46 +00001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_HIDDEN_API_H_
18#define ART_RUNTIME_HIDDEN_API_H_
19
David Brazdil85865692018-10-30 17:26:20 +000020#include "art_field.h"
21#include "art_method.h"
Andreas Gampeb74f3072019-05-01 15:19:00 -070022#include "base/hiddenapi_domain.h"
David Brazdildcfa89b2018-10-31 11:04:10 +000023#include "base/hiddenapi_flags.h"
Andreas Gampe7fbc4a52018-11-28 08:26:47 -080024#include "base/locks.h"
Vladimir Marko492649b2021-10-11 14:21:22 +010025#include "dex/class_accessor.h"
David Brazdil85865692018-10-30 17:26:20 +000026#include "intrinsics_enum.h"
Orion Hodson814b9282020-02-19 16:37:11 +000027#include "jni/jni_internal.h"
Vladimir Marko492649b2021-10-11 14:21:22 +010028#include "mirror/class.h"
29#include "mirror/class_loader.h"
David Brazdil5a61bb72018-01-19 16:59:46 +000030#include "reflection.h"
31#include "runtime.h"
Orion Hodson814b9282020-02-19 16:37:11 +000032#include "well_known_classes.h"
David Brazdil5a61bb72018-01-19 16:59:46 +000033
34namespace art {
35namespace hiddenapi {
36
Mathew Inwood597d7f62018-03-22 11:36:47 +000037// Hidden API enforcement policy
38// This must be kept in sync with ApplicationInfo.ApiEnforcementPolicy in
39// frameworks/base/core/java/android/content/pm/ApplicationInfo.java
40enum class EnforcementPolicy {
David Brazdilf50ac102018-10-17 18:00:06 +010041 kDisabled = 0,
Mathew Inwooda8503d92018-04-05 16:10:25 +010042 kJustWarn = 1, // keep checks enabled, but allow everything (enables logging)
Andrei Oneafc12a6c2020-07-29 19:52:34 +010043 kEnabled = 2, // ban conditionally blocked & blocklist
David Brazdilf50ac102018-10-17 18:00:06 +010044 kMax = kEnabled,
Mathew Inwood597d7f62018-03-22 11:36:47 +000045};
46
47inline EnforcementPolicy EnforcementPolicyFromInt(int api_policy_int) {
48 DCHECK_GE(api_policy_int, 0);
49 DCHECK_LE(api_policy_int, static_cast<int>(EnforcementPolicy::kMax));
50 return static_cast<EnforcementPolicy>(api_policy_int);
51}
52
Andrei Oneaa2d2bc22019-01-25 16:18:53 +000053// Hidden API access method
54// Thist must be kept in sync with VMRuntime.HiddenApiUsageLogger.ACCESS_METHOD_*
David Brazdilf50ac102018-10-17 18:00:06 +010055enum class AccessMethod {
Andrei Oneaa2d2bc22019-01-25 16:18:53 +000056 kNone = 0, // internal test that does not correspond to an actual access by app
57 kReflection = 1,
58 kJNI = 2,
59 kLinking = 3,
Mathew Inwood1fd97f22018-04-03 15:32:32 +010060};
61
David Brazdile7681822018-12-14 16:25:33 +000062// Represents the API domain of a caller/callee.
63class AccessContext {
David Brazdilf50ac102018-10-17 18:00:06 +010064 public:
David Brazdile7681822018-12-14 16:25:33 +000065 // Initialize to either the fully-trusted or fully-untrusted domain.
66 explicit AccessContext(bool is_trusted)
67 : klass_(nullptr),
68 dex_file_(nullptr),
69 domain_(ComputeDomain(is_trusted)) {}
David Brazdilf50ac102018-10-17 18:00:06 +010070
David Brazdile7681822018-12-14 16:25:33 +000071 // Initialize from class loader and dex file (via dex cache).
David Brazdilf50ac102018-10-17 18:00:06 +010072 AccessContext(ObjPtr<mirror::ClassLoader> class_loader, ObjPtr<mirror::DexCache> dex_cache)
David Brazdile7681822018-12-14 16:25:33 +000073 REQUIRES_SHARED(Locks::mutator_lock_)
74 : klass_(nullptr),
75 dex_file_(GetDexFileFromDexCache(dex_cache)),
76 domain_(ComputeDomain(class_loader, dex_file_)) {}
David Brazdilf50ac102018-10-17 18:00:06 +010077
David Brazdila5c3a802019-03-08 14:59:41 +000078 // Initialize from class loader and dex file (only used by tests).
79 AccessContext(ObjPtr<mirror::ClassLoader> class_loader, const DexFile* dex_file)
80 : klass_(nullptr),
81 dex_file_(dex_file),
82 domain_(ComputeDomain(class_loader, dex_file_)) {}
83
David Brazdile7681822018-12-14 16:25:33 +000084 // Initialize from Class.
85 explicit AccessContext(ObjPtr<mirror::Class> klass)
86 REQUIRES_SHARED(Locks::mutator_lock_)
87 : klass_(klass),
88 dex_file_(GetDexFileFromDexCache(klass->GetDexCache())),
89 domain_(ComputeDomain(klass, dex_file_)) {}
90
91 ObjPtr<mirror::Class> GetClass() const { return klass_; }
92 const DexFile* GetDexFile() const { return dex_file_; }
93 Domain GetDomain() const { return domain_; }
David Brazdild51e5742019-02-28 14:47:32 +000094 bool IsApplicationDomain() const { return domain_ == Domain::kApplication; }
David Brazdile7681822018-12-14 16:25:33 +000095
96 // Returns true if this domain is always allowed to access the domain of `callee`.
97 bool CanAlwaysAccess(const AccessContext& callee) const {
98 return IsDomainMoreTrustedThan(domain_, callee.domain_);
99 }
David Brazdilf50ac102018-10-17 18:00:06 +0100100
101 private:
David Brazdile7681822018-12-14 16:25:33 +0000102 static const DexFile* GetDexFileFromDexCache(ObjPtr<mirror::DexCache> dex_cache)
David Brazdilf50ac102018-10-17 18:00:06 +0100103 REQUIRES_SHARED(Locks::mutator_lock_) {
David Brazdile7681822018-12-14 16:25:33 +0000104 return dex_cache.IsNull() ? nullptr : dex_cache->GetDexFile();
David Brazdilf50ac102018-10-17 18:00:06 +0100105 }
106
David Brazdile7681822018-12-14 16:25:33 +0000107 static Domain ComputeDomain(bool is_trusted) {
108 return is_trusted ? Domain::kCorePlatform : Domain::kApplication;
109 }
David Brazdilf50ac102018-10-17 18:00:06 +0100110
David Brazdila5c3a802019-03-08 14:59:41 +0000111 static Domain ComputeDomain(ObjPtr<mirror::ClassLoader> class_loader, const DexFile* dex_file) {
David Brazdile7681822018-12-14 16:25:33 +0000112 if (dex_file == nullptr) {
113 return ComputeDomain(/* is_trusted= */ class_loader.IsNull());
David Brazdilf50ac102018-10-17 18:00:06 +0100114 }
115
David Brazdila5c3a802019-03-08 14:59:41 +0000116 return dex_file->GetHiddenapiDomain();
David Brazdile7681822018-12-14 16:25:33 +0000117 }
118
119 static Domain ComputeDomain(ObjPtr<mirror::Class> klass, const DexFile* dex_file)
120 REQUIRES_SHARED(Locks::mutator_lock_) {
David Brazdilf50ac102018-10-17 18:00:06 +0100121 // Check other aspects of the context.
David Brazdile7681822018-12-14 16:25:33 +0000122 Domain domain = ComputeDomain(klass->GetClassLoader(), dex_file);
123
124 if (domain == Domain::kApplication &&
125 klass->ShouldSkipHiddenApiChecks() &&
126 Runtime::Current()->IsJavaDebuggable()) {
127 // Class is known, it is marked trusted and we are in debuggable mode.
128 domain = ComputeDomain(/* is_trusted= */ true);
129 }
130
131 return domain;
David Brazdilf50ac102018-10-17 18:00:06 +0100132 }
133
David Brazdile7681822018-12-14 16:25:33 +0000134 // Pointer to declaring class of the caller/callee (null if not provided).
135 // This is not safe across GC but we're only using this class for passing
136 // information about the caller to the access check logic and never retain
137 // the AccessContext instance beyond that.
138 const ObjPtr<mirror::Class> klass_;
139
140 // DexFile of the caller/callee (null if not provided).
141 const DexFile* const dex_file_;
142
143 // Computed domain of the caller/callee.
144 const Domain domain_;
David Brazdil068d68d2018-02-12 13:04:17 -0800145};
146
David Brazdil32bde992018-05-14 15:24:34 +0100147class ScopedHiddenApiEnforcementPolicySetting {
148 public:
149 explicit ScopedHiddenApiEnforcementPolicySetting(EnforcementPolicy new_policy)
150 : initial_policy_(Runtime::Current()->GetHiddenApiEnforcementPolicy()) {
151 Runtime::Current()->SetHiddenApiEnforcementPolicy(new_policy);
152 }
153
154 ~ScopedHiddenApiEnforcementPolicySetting() {
155 Runtime::Current()->SetHiddenApiEnforcementPolicy(initial_policy_);
156 }
157
158 private:
159 const EnforcementPolicy initial_policy_;
160 DISALLOW_COPY_AND_ASSIGN(ScopedHiddenApiEnforcementPolicySetting);
161};
162
Orion Hodson814b9282020-02-19 16:37:11 +0000163void InitializeCorePlatformApiPrivateFields() REQUIRES(!Locks::mutator_lock_);
164
Sorin Basca633ac3c2021-10-06 14:00:29 +0000165// Walks the stack, finds the caller of this reflective call and returns
166// a hiddenapi AccessContext formed from its declaring class.
167AccessContext GetReflectionCallerAccessContext(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
168
Andreas Gampeaa120012018-03-28 16:23:24 -0700169// Implementation details. DO NOT ACCESS DIRECTLY.
170namespace detail {
David Brazdilee7d2fd2018-01-20 17:25:23 +0000171
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000172// Class to encapsulate the signature of a member (ArtField or ArtMethod). This
173// is used as a helper when matching prefixes, and when logging the signature.
174class MemberSignature {
175 private:
Mathew Inwood1fd97f22018-04-03 15:32:32 +0100176 enum MemberType {
177 kField,
178 kMethod,
179 };
180
181 std::string class_name_;
182 std::string member_name_;
183 std::string type_signature_;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000184 std::string tmp_;
Mathew Inwood1fd97f22018-04-03 15:32:32 +0100185 MemberType type_;
186
187 inline std::vector<const char*> GetSignatureParts() const;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000188
189 public:
Andreas Gampeaa120012018-03-28 16:23:24 -0700190 explicit MemberSignature(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_);
191 explicit MemberSignature(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdil1a658632018-12-01 17:54:26 +0000192 explicit MemberSignature(const ClassAccessor::Field& field);
193 explicit MemberSignature(const ClassAccessor::Method& method);
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000194
Andreas Gampeaa120012018-03-28 16:23:24 -0700195 void Dump(std::ostream& os) const;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000196
David Brazdil1a658632018-12-01 17:54:26 +0000197 bool Equals(const MemberSignature& other);
198 bool MemberNameAndTypeMatch(const MemberSignature& other);
199
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000200 // Performs prefix match on this member. Since the full member signature is
201 // composed of several parts, we match each part in turn (rather than
202 // building the entire thing in memory and performing a simple prefix match)
Andreas Gampeaa120012018-03-28 16:23:24 -0700203 bool DoesPrefixMatch(const std::string& prefix) const;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000204
Artur Satayev4a1e4dd2020-04-23 22:28:59 +0100205 bool DoesPrefixMatchAny(const std::vector<std::string>& exemptions);
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000206
David Brazdil4de9bb62019-04-03 13:06:17 +0100207 void WarnAboutAccess(AccessMethod access_method, ApiList list, bool access_denied);
Mathew Inwood1fd97f22018-04-03 15:32:32 +0100208
Andrei Onea6ad020d2019-02-18 12:15:51 +0000209 void LogAccessToEventLog(uint32_t sampled_value, AccessMethod access_method, bool access_denied);
David Brazdilf50ac102018-10-17 18:00:06 +0100210
211 // Calls back into managed code to notify VMRuntime.nonSdkApiUsageConsumer that
Andrei Onea02db0722020-08-07 14:56:59 +0100212 // |member| was accessed. This is usually called when an API is unsupported,
213 // conditionally or unconditionally blocked. Given that the callback can execute arbitrary
David Brazdilf50ac102018-10-17 18:00:06 +0100214 // code, a call to this method can result in thread suspension.
215 void NotifyHiddenApiListener(AccessMethod access_method);
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000216};
David Brazdilee7d2fd2018-01-20 17:25:23 +0000217
David Brazdil85865692018-10-30 17:26:20 +0000218// Locates hiddenapi flags for `field` in the corresponding dex file.
219// NB: This is an O(N) operation, linear with the number of members in the class def.
David Brazdil1a658632018-12-01 17:54:26 +0000220template<typename T>
221uint32_t GetDexFlags(T* member) REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdil85865692018-10-30 17:26:20 +0000222
David Brazdild51e5742019-02-28 14:47:32 +0000223// Handler of detected core platform API violations. Returns true if access to
224// `member` should be denied.
Andreas Gampeaa120012018-03-28 16:23:24 -0700225template<typename T>
David Brazdild51e5742019-02-28 14:47:32 +0000226bool HandleCorePlatformApiViolation(T* member,
227 const AccessContext& caller_context,
228 AccessMethod access_method,
229 EnforcementPolicy policy)
David Brazdile7681822018-12-14 16:25:33 +0000230 REQUIRES_SHARED(Locks::mutator_lock_);
231
232template<typename T>
David Brazdilf50ac102018-10-17 18:00:06 +0100233bool ShouldDenyAccessToMemberImpl(T* member, ApiList api_list, AccessMethod access_method)
Andreas Gampeaa120012018-03-28 16:23:24 -0700234 REQUIRES_SHARED(Locks::mutator_lock_);
235
David Brazdil6a1dab42019-02-28 18:45:15 +0000236inline ArtField* GetInterfaceMemberIfProxy(ArtField* field) { return field; }
237
238inline ArtMethod* GetInterfaceMemberIfProxy(ArtMethod* method)
239 REQUIRES_SHARED(Locks::mutator_lock_) {
240 return method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
241}
242
David Brazdil85865692018-10-30 17:26:20 +0000243// Returns access flags for the runtime representation of a class member (ArtField/ArtMember).
David Brazdil31cc2792019-04-10 00:31:15 +0100244ALWAYS_INLINE inline uint32_t CreateRuntimeFlags_Impl(uint32_t dex_flags) {
David Brazdil85865692018-10-30 17:26:20 +0000245 uint32_t runtime_flags = 0u;
246
David Brazdil31cc2792019-04-10 00:31:15 +0100247 ApiList api_list(dex_flags);
David Brazdil90faceb2018-12-14 14:36:15 +0000248 DCHECK(api_list.IsValid());
David Brazdil85865692018-10-30 17:26:20 +0000249
Andrei Oneafc12a6c2020-07-29 19:52:34 +0100250 if (api_list.Contains(ApiList::Sdk())) {
David Brazdil85865692018-10-30 17:26:20 +0000251 runtime_flags |= kAccPublicApi;
David Brazdil90faceb2018-12-14 14:36:15 +0000252 } else {
253 // Only add domain-specific flags for non-public API members.
254 // This simplifies hardcoded values for intrinsics.
255 if (api_list.Contains(ApiList::CorePlatformApi())) {
256 runtime_flags |= kAccCorePlatformApi;
257 }
David Brazdil85865692018-10-30 17:26:20 +0000258 }
259
260 DCHECK_EQ(runtime_flags & kAccHiddenapiBits, runtime_flags)
261 << "Runtime flags not in reserved access flags bits";
262 return runtime_flags;
263}
264
David Brazdil31cc2792019-04-10 00:31:15 +0100265} // namespace detail
266
267// Returns access flags for the runtime representation of a class member (ArtField/ArtMember).
268ALWAYS_INLINE inline uint32_t CreateRuntimeFlags(const ClassAccessor::BaseItem& member) {
269 return detail::CreateRuntimeFlags_Impl(member.GetHiddenapiFlags());
270}
271
272// Returns access flags for the runtime representation of a class member (ArtField/ArtMember).
273template<typename T>
274ALWAYS_INLINE inline uint32_t CreateRuntimeFlags(T* member) REQUIRES_SHARED(Locks::mutator_lock_) {
275 return detail::CreateRuntimeFlags_Impl(detail::GetDexFlags(member));
276}
277
David Brazdil85865692018-10-30 17:26:20 +0000278// Extracts hiddenapi runtime flags from access flags of ArtField.
279ALWAYS_INLINE inline uint32_t GetRuntimeFlags(ArtField* field)
280 REQUIRES_SHARED(Locks::mutator_lock_) {
281 return field->GetAccessFlags() & kAccHiddenapiBits;
282}
283
284// Extracts hiddenapi runtime flags from access flags of ArtMethod.
285// Uses hardcoded values for intrinsics.
286ALWAYS_INLINE inline uint32_t GetRuntimeFlags(ArtMethod* method)
287 REQUIRES_SHARED(Locks::mutator_lock_) {
288 if (UNLIKELY(method->IsIntrinsic())) {
289 switch (static_cast<Intrinsics>(method->GetIntrinsic())) {
290 case Intrinsics::kSystemArrayCopyChar:
291 case Intrinsics::kStringGetCharsNoCheck:
292 case Intrinsics::kReferenceGetReferent:
Vladimir Markoac27ac02021-02-01 09:31:02 +0000293 case Intrinsics::kReferenceRefersTo:
David Brazdil85865692018-10-30 17:26:20 +0000294 case Intrinsics::kMemoryPeekByte:
295 case Intrinsics::kMemoryPokeByte:
David Brazdil85865692018-10-30 17:26:20 +0000296 case Intrinsics::kCRC32Update:
Evgeny Astigeevich15c5b972018-11-20 13:41:40 +0000297 case Intrinsics::kCRC32UpdateBytes:
Evgeny Astigeevich776a7c22018-12-17 11:40:34 +0000298 case Intrinsics::kCRC32UpdateByteBuffer:
David Brazdil85865692018-10-30 17:26:20 +0000299 case Intrinsics::kStringNewStringFromBytes:
300 case Intrinsics::kStringNewStringFromChars:
301 case Intrinsics::kStringNewStringFromString:
302 case Intrinsics::kMemoryPeekIntNative:
303 case Intrinsics::kMemoryPeekLongNative:
304 case Intrinsics::kMemoryPeekShortNative:
305 case Intrinsics::kMemoryPokeIntNative:
306 case Intrinsics::kMemoryPokeLongNative:
307 case Intrinsics::kMemoryPokeShortNative:
Orion Hodson53f9e652020-02-26 10:27:05 +0000308 case Intrinsics::kUnsafeCASInt:
309 case Intrinsics::kUnsafeCASLong:
310 case Intrinsics::kUnsafeCASObject:
311 case Intrinsics::kUnsafeGetAndAddInt:
312 case Intrinsics::kUnsafeGetAndAddLong:
313 case Intrinsics::kUnsafeGetAndSetInt:
314 case Intrinsics::kUnsafeGetAndSetLong:
315 case Intrinsics::kUnsafeGetAndSetObject:
316 case Intrinsics::kUnsafeGetLongVolatile:
317 case Intrinsics::kUnsafeGetObjectVolatile:
318 case Intrinsics::kUnsafeGetVolatile:
319 case Intrinsics::kUnsafePutLongOrdered:
320 case Intrinsics::kUnsafePutLongVolatile:
321 case Intrinsics::kUnsafePutObjectOrdered:
322 case Intrinsics::kUnsafePutObjectVolatile:
323 case Intrinsics::kUnsafePutOrdered:
324 case Intrinsics::kUnsafePutVolatile:
325 case Intrinsics::kUnsafeLoadFence:
326 case Intrinsics::kUnsafeStoreFence:
327 case Intrinsics::kUnsafeFullFence:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000328 case Intrinsics::kJdkUnsafeCASInt:
329 case Intrinsics::kJdkUnsafeCASLong:
330 case Intrinsics::kJdkUnsafeCASObject:
Sorin Basca0069ad72021-09-17 17:33:09 +0000331 case Intrinsics::kJdkUnsafeCompareAndSetInt:
Sorin Basca507cf902021-10-06 12:04:56 +0000332 case Intrinsics::kJdkUnsafeCompareAndSetLong:
333 case Intrinsics::kJdkUnsafeCompareAndSetObject:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000334 case Intrinsics::kJdkUnsafeGetAndAddInt:
335 case Intrinsics::kJdkUnsafeGetAndAddLong:
336 case Intrinsics::kJdkUnsafeGetAndSetInt:
337 case Intrinsics::kJdkUnsafeGetAndSetLong:
338 case Intrinsics::kJdkUnsafeGetAndSetObject:
339 case Intrinsics::kJdkUnsafeGetLongVolatile:
Sorin Basca507cf902021-10-06 12:04:56 +0000340 case Intrinsics::kJdkUnsafeGetLongAcquire:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000341 case Intrinsics::kJdkUnsafeGetObjectVolatile:
Sorin Basca507cf902021-10-06 12:04:56 +0000342 case Intrinsics::kJdkUnsafeGetObjectAcquire:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000343 case Intrinsics::kJdkUnsafeGetVolatile:
Sorin Basca0069ad72021-09-17 17:33:09 +0000344 case Intrinsics::kJdkUnsafeGetAcquire:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000345 case Intrinsics::kJdkUnsafePutLongOrdered:
346 case Intrinsics::kJdkUnsafePutLongVolatile:
Sorin Basca507cf902021-10-06 12:04:56 +0000347 case Intrinsics::kJdkUnsafePutLongRelease:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000348 case Intrinsics::kJdkUnsafePutObjectOrdered:
349 case Intrinsics::kJdkUnsafePutObjectVolatile:
Sorin Basca507cf902021-10-06 12:04:56 +0000350 case Intrinsics::kJdkUnsafePutObjectRelease:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000351 case Intrinsics::kJdkUnsafePutOrdered:
352 case Intrinsics::kJdkUnsafePutVolatile:
Sorin Basca0069ad72021-09-17 17:33:09 +0000353 case Intrinsics::kJdkUnsafePutRelease:
Sorin Basca2f01e8e2021-06-18 06:44:07 +0000354 case Intrinsics::kJdkUnsafeLoadFence:
355 case Intrinsics::kJdkUnsafeStoreFence:
356 case Intrinsics::kJdkUnsafeFullFence:
357 case Intrinsics::kJdkUnsafeGet:
358 case Intrinsics::kJdkUnsafeGetLong:
359 case Intrinsics::kJdkUnsafeGetObject:
360 case Intrinsics::kJdkUnsafePutLong:
361 case Intrinsics::kJdkUnsafePut:
362 case Intrinsics::kJdkUnsafePutObject:
David Brazdil85865692018-10-30 17:26:20 +0000363 return 0u;
Usama Arif665aac42019-10-29 11:13:18 +0000364 case Intrinsics::kFP16Ceil:
Usama Arifecbdc072019-11-13 13:32:54 +0000365 case Intrinsics::kFP16Compare:
Usama Arifb9f02c22019-10-25 17:37:33 +0100366 case Intrinsics::kFP16Floor:
Usama Arif457e9fa2019-11-11 15:29:59 +0000367 case Intrinsics::kFP16Greater:
368 case Intrinsics::kFP16GreaterEquals:
369 case Intrinsics::kFP16Less:
370 case Intrinsics::kFP16LessEquals:
Usama Arif39e29792019-11-15 10:53:29 +0000371 case Intrinsics::kFP16Min:
372 case Intrinsics::kFP16Max:
xueliang.zhong9ce340f2019-01-22 17:46:09 +0000373 case Intrinsics::kFP16ToFloat:
Vladimir Marko7f958e32019-10-24 09:03:58 +0000374 case Intrinsics::kFP16ToHalf:
Usama Arif681692b2019-10-30 16:23:26 +0000375 case Intrinsics::kFP16Rint:
Orion Hodson53f9e652020-02-26 10:27:05 +0000376 case Intrinsics::kUnsafeGet:
377 case Intrinsics::kUnsafeGetLong:
378 case Intrinsics::kUnsafeGetObject:
379 case Intrinsics::kUnsafePutLong:
380 case Intrinsics::kUnsafePut:
381 case Intrinsics::kUnsafePutObject:
David Brazdilc63d5662019-04-10 00:31:46 +0100382 return kAccCorePlatformApi;
David Brazdil85865692018-10-30 17:26:20 +0000383 default:
384 // Remaining intrinsics are public API. We DCHECK that in SetIntrinsic().
385 return kAccPublicApi;
386 }
387 } else {
388 return method->GetAccessFlags() & kAccHiddenapiBits;
389 }
390}
391
David Brazdila5c3a802019-03-08 14:59:41 +0000392// Called by class linker when a new dex file has been registered. Assigns
393// the AccessContext domain to the newly-registered dex file based on its
394// location and class loader.
395void InitializeDexFileDomain(const DexFile& dex_file, ObjPtr<mirror::ClassLoader> class_loader);
396
David Brazdilf50ac102018-10-17 18:00:06 +0100397// Returns true if access to `member` should be denied in the given context.
398// The decision is based on whether the caller is in a trusted context or not.
399// Because determining the access context can be expensive, a lambda function
400// "fn_get_access_context" is lazily invoked after other criteria have been
401// considered.
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000402// This function might print warnings into the log if the member is hidden.
David Brazdilee7d2fd2018-01-20 17:25:23 +0000403template<typename T>
Vladimir Marko492649b2021-10-11 14:21:22 +0100404bool ShouldDenyAccessToMember(T* member,
405 const std::function<AccessContext()>& fn_get_access_context,
406 AccessMethod access_method)
407 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdil8e1a7cb2018-03-27 08:14:25 +0000408
David Brazdilf50ac102018-10-17 18:00:06 +0100409// Helper method for callers where access context can be determined beforehand.
410// Wraps AccessContext in a lambda and passes it to the real ShouldDenyAccessToMember.
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000411template<typename T>
David Brazdilf50ac102018-10-17 18:00:06 +0100412inline bool ShouldDenyAccessToMember(T* member,
David Brazdile7681822018-12-14 16:25:33 +0000413 const AccessContext& access_context,
David Brazdilf50ac102018-10-17 18:00:06 +0100414 AccessMethod access_method)
David Brazdilee7d2fd2018-01-20 17:25:23 +0000415 REQUIRES_SHARED(Locks::mutator_lock_) {
David Brazdile7681822018-12-14 16:25:33 +0000416 return ShouldDenyAccessToMember(member, [&]() { return access_context; }, access_method);
David Brazdilee7d2fd2018-01-20 17:25:23 +0000417}
418
David Brazdil5a61bb72018-01-19 16:59:46 +0000419} // namespace hiddenapi
420} // namespace art
421
422#endif // ART_RUNTIME_HIDDEN_API_H_