blob: e15e9f38aa01f143f964b2fe1b83a50d95937d32 [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"
David Brazdildcfa89b2018-10-31 11:04:10 +000022#include "base/hiddenapi_flags.h"
Andreas Gampe7fbc4a52018-11-28 08:26:47 -080023#include "base/locks.h"
David Brazdil85865692018-10-30 17:26:20 +000024#include "intrinsics_enum.h"
David Brazdil8ce3bfa2018-03-12 18:01:18 +000025#include "mirror/class-inl.h"
David Brazdil5a61bb72018-01-19 16:59:46 +000026#include "reflection.h"
27#include "runtime.h"
28
29namespace art {
30namespace hiddenapi {
31
Mathew Inwood597d7f62018-03-22 11:36:47 +000032// Hidden API enforcement policy
33// This must be kept in sync with ApplicationInfo.ApiEnforcementPolicy in
34// frameworks/base/core/java/android/content/pm/ApplicationInfo.java
35enum class EnforcementPolicy {
David Brazdilf50ac102018-10-17 18:00:06 +010036 kDisabled = 0,
Mathew Inwooda8503d92018-04-05 16:10:25 +010037 kJustWarn = 1, // keep checks enabled, but allow everything (enables logging)
David Brazdilf50ac102018-10-17 18:00:06 +010038 kEnabled = 2, // ban dark grey & blacklist
39 kMax = kEnabled,
Mathew Inwood597d7f62018-03-22 11:36:47 +000040};
41
42inline EnforcementPolicy EnforcementPolicyFromInt(int api_policy_int) {
43 DCHECK_GE(api_policy_int, 0);
44 DCHECK_LE(api_policy_int, static_cast<int>(EnforcementPolicy::kMax));
45 return static_cast<EnforcementPolicy>(api_policy_int);
46}
47
Andrei Oneaa2d2bc22019-01-25 16:18:53 +000048// Hidden API access method
49// Thist must be kept in sync with VMRuntime.HiddenApiUsageLogger.ACCESS_METHOD_*
David Brazdilf50ac102018-10-17 18:00:06 +010050enum class AccessMethod {
Andrei Oneaa2d2bc22019-01-25 16:18:53 +000051 kNone = 0, // internal test that does not correspond to an actual access by app
52 kReflection = 1,
53 kJNI = 2,
54 kLinking = 3,
Mathew Inwood1fd97f22018-04-03 15:32:32 +010055};
56
David Brazdile7681822018-12-14 16:25:33 +000057// Represents the API domain of a caller/callee.
58class AccessContext {
David Brazdilf50ac102018-10-17 18:00:06 +010059 public:
David Brazdile7681822018-12-14 16:25:33 +000060 // Initialize to either the fully-trusted or fully-untrusted domain.
61 explicit AccessContext(bool is_trusted)
62 : klass_(nullptr),
63 dex_file_(nullptr),
64 domain_(ComputeDomain(is_trusted)) {}
David Brazdilf50ac102018-10-17 18:00:06 +010065
David Brazdile7681822018-12-14 16:25:33 +000066 // Initialize from class loader and dex file (via dex cache).
David Brazdilf50ac102018-10-17 18:00:06 +010067 AccessContext(ObjPtr<mirror::ClassLoader> class_loader, ObjPtr<mirror::DexCache> dex_cache)
David Brazdile7681822018-12-14 16:25:33 +000068 REQUIRES_SHARED(Locks::mutator_lock_)
69 : klass_(nullptr),
70 dex_file_(GetDexFileFromDexCache(dex_cache)),
71 domain_(ComputeDomain(class_loader, dex_file_)) {}
David Brazdilf50ac102018-10-17 18:00:06 +010072
David Brazdile7681822018-12-14 16:25:33 +000073 // Initialize from Class.
74 explicit AccessContext(ObjPtr<mirror::Class> klass)
75 REQUIRES_SHARED(Locks::mutator_lock_)
76 : klass_(klass),
77 dex_file_(GetDexFileFromDexCache(klass->GetDexCache())),
78 domain_(ComputeDomain(klass, dex_file_)) {}
79
80 ObjPtr<mirror::Class> GetClass() const { return klass_; }
81 const DexFile* GetDexFile() const { return dex_file_; }
82 Domain GetDomain() const { return domain_; }
83
84 bool IsUntrustedDomain() const { return domain_ == Domain::kApplication; }
85
86 // Returns true if this domain is always allowed to access the domain of `callee`.
87 bool CanAlwaysAccess(const AccessContext& callee) const {
88 return IsDomainMoreTrustedThan(domain_, callee.domain_);
89 }
David Brazdilf50ac102018-10-17 18:00:06 +010090
91 private:
David Brazdile7681822018-12-14 16:25:33 +000092 static const DexFile* GetDexFileFromDexCache(ObjPtr<mirror::DexCache> dex_cache)
David Brazdilf50ac102018-10-17 18:00:06 +010093 REQUIRES_SHARED(Locks::mutator_lock_) {
David Brazdile7681822018-12-14 16:25:33 +000094 return dex_cache.IsNull() ? nullptr : dex_cache->GetDexFile();
David Brazdilf50ac102018-10-17 18:00:06 +010095 }
96
David Brazdile7681822018-12-14 16:25:33 +000097 static Domain ComputeDomain(bool is_trusted) {
98 return is_trusted ? Domain::kCorePlatform : Domain::kApplication;
99 }
David Brazdilf50ac102018-10-17 18:00:06 +0100100
David Brazdile7681822018-12-14 16:25:33 +0000101 static Domain ComputeDomain(ObjPtr<mirror::ClassLoader> class_loader, const DexFile* dex_file)
102 REQUIRES_SHARED(Locks::mutator_lock_) {
103 if (dex_file == nullptr) {
104 return ComputeDomain(/* is_trusted= */ class_loader.IsNull());
David Brazdilf50ac102018-10-17 18:00:06 +0100105 }
106
David Brazdile7681822018-12-14 16:25:33 +0000107 Domain dex_domain = dex_file->GetHiddenapiDomain();
108 if (class_loader.IsNull() && dex_domain == Domain::kApplication) {
David Brazdila6d61842019-01-22 22:44:11 +0000109 // LOG(WARNING) << "DexFile " << dex_file->GetLocation() << " is in boot classpath "
110 // << "but is assigned untrusted domain";
David Brazdile7681822018-12-14 16:25:33 +0000111 dex_domain = Domain::kPlatform;
112 }
113 return dex_domain;
114 }
115
116 static Domain ComputeDomain(ObjPtr<mirror::Class> klass, const DexFile* dex_file)
117 REQUIRES_SHARED(Locks::mutator_lock_) {
David Brazdilf50ac102018-10-17 18:00:06 +0100118 // Check other aspects of the context.
David Brazdile7681822018-12-14 16:25:33 +0000119 Domain domain = ComputeDomain(klass->GetClassLoader(), dex_file);
120
121 if (domain == Domain::kApplication &&
122 klass->ShouldSkipHiddenApiChecks() &&
123 Runtime::Current()->IsJavaDebuggable()) {
124 // Class is known, it is marked trusted and we are in debuggable mode.
125 domain = ComputeDomain(/* is_trusted= */ true);
126 }
127
128 return domain;
David Brazdilf50ac102018-10-17 18:00:06 +0100129 }
130
David Brazdile7681822018-12-14 16:25:33 +0000131 // Pointer to declaring class of the caller/callee (null if not provided).
132 // This is not safe across GC but we're only using this class for passing
133 // information about the caller to the access check logic and never retain
134 // the AccessContext instance beyond that.
135 const ObjPtr<mirror::Class> klass_;
136
137 // DexFile of the caller/callee (null if not provided).
138 const DexFile* const dex_file_;
139
140 // Computed domain of the caller/callee.
141 const Domain domain_;
David Brazdil068d68d2018-02-12 13:04:17 -0800142};
143
David Brazdil32bde992018-05-14 15:24:34 +0100144class ScopedHiddenApiEnforcementPolicySetting {
145 public:
146 explicit ScopedHiddenApiEnforcementPolicySetting(EnforcementPolicy new_policy)
147 : initial_policy_(Runtime::Current()->GetHiddenApiEnforcementPolicy()) {
148 Runtime::Current()->SetHiddenApiEnforcementPolicy(new_policy);
149 }
150
151 ~ScopedHiddenApiEnforcementPolicySetting() {
152 Runtime::Current()->SetHiddenApiEnforcementPolicy(initial_policy_);
153 }
154
155 private:
156 const EnforcementPolicy initial_policy_;
157 DISALLOW_COPY_AND_ASSIGN(ScopedHiddenApiEnforcementPolicySetting);
158};
159
Andreas Gampeaa120012018-03-28 16:23:24 -0700160// Implementation details. DO NOT ACCESS DIRECTLY.
161namespace detail {
David Brazdilee7d2fd2018-01-20 17:25:23 +0000162
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000163// Class to encapsulate the signature of a member (ArtField or ArtMethod). This
164// is used as a helper when matching prefixes, and when logging the signature.
165class MemberSignature {
166 private:
Mathew Inwood1fd97f22018-04-03 15:32:32 +0100167 enum MemberType {
168 kField,
169 kMethod,
170 };
171
172 std::string class_name_;
173 std::string member_name_;
174 std::string type_signature_;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000175 std::string tmp_;
Mathew Inwood1fd97f22018-04-03 15:32:32 +0100176 MemberType type_;
177
178 inline std::vector<const char*> GetSignatureParts() const;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000179
180 public:
Andreas Gampeaa120012018-03-28 16:23:24 -0700181 explicit MemberSignature(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_);
182 explicit MemberSignature(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdil1a658632018-12-01 17:54:26 +0000183 explicit MemberSignature(const ClassAccessor::Field& field);
184 explicit MemberSignature(const ClassAccessor::Method& method);
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000185
Andreas Gampeaa120012018-03-28 16:23:24 -0700186 void Dump(std::ostream& os) const;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000187
David Brazdil1a658632018-12-01 17:54:26 +0000188 bool Equals(const MemberSignature& other);
189 bool MemberNameAndTypeMatch(const MemberSignature& other);
190
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000191 // Performs prefix match on this member. Since the full member signature is
192 // composed of several parts, we match each part in turn (rather than
193 // building the entire thing in memory and performing a simple prefix match)
Andreas Gampeaa120012018-03-28 16:23:24 -0700194 bool DoesPrefixMatch(const std::string& prefix) const;
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000195
Andreas Gampeaa120012018-03-28 16:23:24 -0700196 bool IsExempted(const std::vector<std::string>& exemptions);
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000197
David Brazdil47cd2722018-10-23 12:50:02 +0100198 void WarnAboutAccess(AccessMethod access_method, ApiList list);
Mathew Inwood1fd97f22018-04-03 15:32:32 +0100199
David Brazdilf50ac102018-10-17 18:00:06 +0100200 void LogAccessToEventLog(AccessMethod access_method, bool access_denied);
201
202 // Calls back into managed code to notify VMRuntime.nonSdkApiUsageConsumer that
203 // |member| was accessed. This is usually called when an API is on the black,
204 // dark grey or light grey lists. Given that the callback can execute arbitrary
205 // code, a call to this method can result in thread suspension.
206 void NotifyHiddenApiListener(AccessMethod access_method);
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000207};
David Brazdilee7d2fd2018-01-20 17:25:23 +0000208
David Brazdil85865692018-10-30 17:26:20 +0000209// Locates hiddenapi flags for `field` in the corresponding dex file.
210// NB: This is an O(N) operation, linear with the number of members in the class def.
David Brazdil1a658632018-12-01 17:54:26 +0000211template<typename T>
212uint32_t GetDexFlags(T* member) REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdil85865692018-10-30 17:26:20 +0000213
Andreas Gampeaa120012018-03-28 16:23:24 -0700214template<typename T>
David Brazdile7681822018-12-14 16:25:33 +0000215void MaybeReportCorePlatformApiViolation(T* member,
216 const AccessContext& caller_context,
217 AccessMethod access_method)
218 REQUIRES_SHARED(Locks::mutator_lock_);
219
220template<typename T>
David Brazdilf50ac102018-10-17 18:00:06 +0100221bool ShouldDenyAccessToMemberImpl(T* member, ApiList api_list, AccessMethod access_method)
Andreas Gampeaa120012018-03-28 16:23:24 -0700222 REQUIRES_SHARED(Locks::mutator_lock_);
223
Andreas Gampeaa120012018-03-28 16:23:24 -0700224} // namespace detail
225
David Brazdil85865692018-10-30 17:26:20 +0000226// Returns access flags for the runtime representation of a class member (ArtField/ArtMember).
227ALWAYS_INLINE inline uint32_t CreateRuntimeFlags(const ClassAccessor::BaseItem& member) {
228 uint32_t runtime_flags = 0u;
229
David Brazdil90faceb2018-12-14 14:36:15 +0000230 ApiList api_list(member.GetHiddenapiFlags());
231 DCHECK(api_list.IsValid());
David Brazdil85865692018-10-30 17:26:20 +0000232
David Brazdil90faceb2018-12-14 14:36:15 +0000233 if (api_list.Contains(ApiList::Whitelist())) {
David Brazdil85865692018-10-30 17:26:20 +0000234 runtime_flags |= kAccPublicApi;
David Brazdil90faceb2018-12-14 14:36:15 +0000235 } else {
236 // Only add domain-specific flags for non-public API members.
237 // This simplifies hardcoded values for intrinsics.
238 if (api_list.Contains(ApiList::CorePlatformApi())) {
239 runtime_flags |= kAccCorePlatformApi;
240 }
David Brazdil85865692018-10-30 17:26:20 +0000241 }
242
243 DCHECK_EQ(runtime_flags & kAccHiddenapiBits, runtime_flags)
244 << "Runtime flags not in reserved access flags bits";
245 return runtime_flags;
246}
247
248// Extracts hiddenapi runtime flags from access flags of ArtField.
249ALWAYS_INLINE inline uint32_t GetRuntimeFlags(ArtField* field)
250 REQUIRES_SHARED(Locks::mutator_lock_) {
251 return field->GetAccessFlags() & kAccHiddenapiBits;
252}
253
254// Extracts hiddenapi runtime flags from access flags of ArtMethod.
255// Uses hardcoded values for intrinsics.
256ALWAYS_INLINE inline uint32_t GetRuntimeFlags(ArtMethod* method)
257 REQUIRES_SHARED(Locks::mutator_lock_) {
258 if (UNLIKELY(method->IsIntrinsic())) {
259 switch (static_cast<Intrinsics>(method->GetIntrinsic())) {
260 case Intrinsics::kSystemArrayCopyChar:
261 case Intrinsics::kStringGetCharsNoCheck:
262 case Intrinsics::kReferenceGetReferent:
263 case Intrinsics::kMemoryPeekByte:
264 case Intrinsics::kMemoryPokeByte:
265 case Intrinsics::kUnsafeCASInt:
266 case Intrinsics::kUnsafeCASLong:
267 case Intrinsics::kUnsafeCASObject:
268 case Intrinsics::kUnsafeGet:
269 case Intrinsics::kUnsafeGetAndAddInt:
270 case Intrinsics::kUnsafeGetAndAddLong:
271 case Intrinsics::kUnsafeGetAndSetInt:
272 case Intrinsics::kUnsafeGetAndSetLong:
273 case Intrinsics::kUnsafeGetAndSetObject:
274 case Intrinsics::kUnsafeGetLong:
275 case Intrinsics::kUnsafeGetLongVolatile:
276 case Intrinsics::kUnsafeGetObject:
277 case Intrinsics::kUnsafeGetObjectVolatile:
278 case Intrinsics::kUnsafeGetVolatile:
279 case Intrinsics::kUnsafePut:
280 case Intrinsics::kUnsafePutLong:
281 case Intrinsics::kUnsafePutLongOrdered:
282 case Intrinsics::kUnsafePutLongVolatile:
283 case Intrinsics::kUnsafePutObject:
284 case Intrinsics::kUnsafePutObjectOrdered:
285 case Intrinsics::kUnsafePutObjectVolatile:
286 case Intrinsics::kUnsafePutOrdered:
287 case Intrinsics::kUnsafePutVolatile:
288 case Intrinsics::kUnsafeLoadFence:
289 case Intrinsics::kUnsafeStoreFence:
290 case Intrinsics::kUnsafeFullFence:
291 case Intrinsics::kCRC32Update:
Evgeny Astigeevich15c5b972018-11-20 13:41:40 +0000292 case Intrinsics::kCRC32UpdateBytes:
Evgeny Astigeevich776a7c22018-12-17 11:40:34 +0000293 case Intrinsics::kCRC32UpdateByteBuffer:
David Brazdil85865692018-10-30 17:26:20 +0000294 case Intrinsics::kStringNewStringFromBytes:
295 case Intrinsics::kStringNewStringFromChars:
296 case Intrinsics::kStringNewStringFromString:
297 case Intrinsics::kMemoryPeekIntNative:
298 case Intrinsics::kMemoryPeekLongNative:
299 case Intrinsics::kMemoryPeekShortNative:
300 case Intrinsics::kMemoryPokeIntNative:
301 case Intrinsics::kMemoryPokeLongNative:
302 case Intrinsics::kMemoryPokeShortNative:
303 case Intrinsics::kVarHandleFullFence:
304 case Intrinsics::kVarHandleAcquireFence:
305 case Intrinsics::kVarHandleReleaseFence:
306 case Intrinsics::kVarHandleLoadLoadFence:
307 case Intrinsics::kVarHandleStoreStoreFence:
308 case Intrinsics::kVarHandleCompareAndExchange:
309 case Intrinsics::kVarHandleCompareAndExchangeAcquire:
310 case Intrinsics::kVarHandleCompareAndExchangeRelease:
311 case Intrinsics::kVarHandleCompareAndSet:
312 case Intrinsics::kVarHandleGet:
313 case Intrinsics::kVarHandleGetAcquire:
314 case Intrinsics::kVarHandleGetAndAdd:
315 case Intrinsics::kVarHandleGetAndAddAcquire:
316 case Intrinsics::kVarHandleGetAndAddRelease:
317 case Intrinsics::kVarHandleGetAndBitwiseAnd:
318 case Intrinsics::kVarHandleGetAndBitwiseAndAcquire:
319 case Intrinsics::kVarHandleGetAndBitwiseAndRelease:
320 case Intrinsics::kVarHandleGetAndBitwiseOr:
321 case Intrinsics::kVarHandleGetAndBitwiseOrAcquire:
322 case Intrinsics::kVarHandleGetAndBitwiseOrRelease:
323 case Intrinsics::kVarHandleGetAndBitwiseXor:
324 case Intrinsics::kVarHandleGetAndBitwiseXorAcquire:
325 case Intrinsics::kVarHandleGetAndBitwiseXorRelease:
326 case Intrinsics::kVarHandleGetAndSet:
327 case Intrinsics::kVarHandleGetAndSetAcquire:
328 case Intrinsics::kVarHandleGetAndSetRelease:
329 case Intrinsics::kVarHandleGetOpaque:
330 case Intrinsics::kVarHandleGetVolatile:
331 case Intrinsics::kVarHandleSet:
332 case Intrinsics::kVarHandleSetOpaque:
333 case Intrinsics::kVarHandleSetRelease:
334 case Intrinsics::kVarHandleSetVolatile:
335 case Intrinsics::kVarHandleWeakCompareAndSet:
336 case Intrinsics::kVarHandleWeakCompareAndSetAcquire:
337 case Intrinsics::kVarHandleWeakCompareAndSetPlain:
338 case Intrinsics::kVarHandleWeakCompareAndSetRelease:
339 return 0u;
340 default:
341 // Remaining intrinsics are public API. We DCHECK that in SetIntrinsic().
342 return kAccPublicApi;
343 }
344 } else {
345 return method->GetAccessFlags() & kAccHiddenapiBits;
346 }
347}
348
David Brazdilf50ac102018-10-17 18:00:06 +0100349// Returns true if access to `member` should be denied in the given context.
350// The decision is based on whether the caller is in a trusted context or not.
351// Because determining the access context can be expensive, a lambda function
352// "fn_get_access_context" is lazily invoked after other criteria have been
353// considered.
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000354// This function might print warnings into the log if the member is hidden.
David Brazdilee7d2fd2018-01-20 17:25:23 +0000355template<typename T>
David Brazdilf50ac102018-10-17 18:00:06 +0100356inline bool ShouldDenyAccessToMember(T* member,
357 std::function<AccessContext()> fn_get_access_context,
358 AccessMethod access_method)
David Brazdilee7d2fd2018-01-20 17:25:23 +0000359 REQUIRES_SHARED(Locks::mutator_lock_) {
360 DCHECK(member != nullptr);
David Brazdile7681822018-12-14 16:25:33 +0000361 const uint32_t runtime_flags = GetRuntimeFlags(member);
David Brazdilee7d2fd2018-01-20 17:25:23 +0000362
David Brazdil85865692018-10-30 17:26:20 +0000363 // Exit early if member is public API. This flag is also set for non-boot class
364 // path fields/methods.
David Brazdile7681822018-12-14 16:25:33 +0000365 if ((runtime_flags & kAccPublicApi) != 0) {
David Brazdilf50ac102018-10-17 18:00:06 +0100366 return false;
David Brazdila02cb112018-01-31 11:36:39 +0000367 }
368
David Brazdile7681822018-12-14 16:25:33 +0000369 // Determine which domain the caller and callee belong to.
370 // This can be *very* expensive. This is why ShouldDenyAccessToMember
371 // should not be called on every individual access.
372 const AccessContext caller_context = fn_get_access_context();
373 const AccessContext callee_context(member->GetDeclaringClass());
374
375 // Non-boot classpath callers should have exited early.
376 DCHECK(!callee_context.IsUntrustedDomain());
377
378 // Check if the caller is always allowed to access members in the callee context.
379 if (caller_context.CanAlwaysAccess(callee_context)) {
David Brazdilc5a96e42019-01-09 10:04:45 +0000380 return false;
381 }
382
David Brazdile7681822018-12-14 16:25:33 +0000383 // Check if this is platform accessing core platform. We may warn if `member` is
384 // not part of core platform API.
385 switch (caller_context.GetDomain()) {
386 case Domain::kApplication: {
387 DCHECK(!callee_context.IsUntrustedDomain());
388
389 // Exit early if access checks are completely disabled.
390 EnforcementPolicy policy = Runtime::Current()->GetHiddenApiEnforcementPolicy();
391 if (policy == EnforcementPolicy::kDisabled) {
392 return false;
393 }
394
395 // Decode hidden API access flags from the dex file.
396 // This is an O(N) operation scaling with the number of fields/methods
397 // in the class. Only do this on slow path and only do it once.
398 ApiList api_list(detail::GetDexFlags(member));
399 DCHECK(api_list.IsValid());
400
401 // Member is hidden and caller is not exempted. Enter slow path.
402 return detail::ShouldDenyAccessToMemberImpl(member, api_list, access_method);
403 }
404
405 case Domain::kPlatform: {
406 DCHECK(callee_context.GetDomain() == Domain::kCorePlatform);
407
408 // Member is part of core platform API. Accessing it is allowed.
409 if ((runtime_flags & kAccCorePlatformApi) != 0) {
410 return false;
411 }
412
413 // Allow access if access checks are disabled.
414 EnforcementPolicy policy = Runtime::Current()->GetCorePlatformApiEnforcementPolicy();
415 if (policy == EnforcementPolicy::kDisabled) {
416 return false;
417 }
418
419 // Access checks are not disabled, report the violation.
David Brazdila6d61842019-01-22 22:44:11 +0000420 // detail::MaybeReportCorePlatformApiViolation(member, caller_context, access_method);
David Brazdile7681822018-12-14 16:25:33 +0000421
422 // Deny access if the policy is enabled.
423 return policy == EnforcementPolicy::kEnabled;
424 }
425
426 case Domain::kCorePlatform: {
427 LOG(FATAL) << "CorePlatform domain should be allowed to access all domains";
428 UNREACHABLE();
429 }
David Brazdila02cb112018-01-31 11:36:39 +0000430 }
David Brazdil8e1a7cb2018-03-27 08:14:25 +0000431}
432
David Brazdilf50ac102018-10-17 18:00:06 +0100433// Helper method for callers where access context can be determined beforehand.
434// Wraps AccessContext in a lambda and passes it to the real ShouldDenyAccessToMember.
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000435template<typename T>
David Brazdilf50ac102018-10-17 18:00:06 +0100436inline bool ShouldDenyAccessToMember(T* member,
David Brazdile7681822018-12-14 16:25:33 +0000437 const AccessContext& access_context,
David Brazdilf50ac102018-10-17 18:00:06 +0100438 AccessMethod access_method)
David Brazdilee7d2fd2018-01-20 17:25:23 +0000439 REQUIRES_SHARED(Locks::mutator_lock_) {
David Brazdile7681822018-12-14 16:25:33 +0000440 return ShouldDenyAccessToMember(member, [&]() { return access_context; }, access_method);
David Brazdilee7d2fd2018-01-20 17:25:23 +0000441}
442
David Brazdil5a61bb72018-01-19 16:59:46 +0000443} // namespace hiddenapi
444} // namespace art
445
446#endif // ART_RUNTIME_HIDDEN_API_H_