blob: 241850ed6e0df417190cd8295cfc47a576eb6f93 [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
20#include "hidden_api_access_flags.h"
21#include "reflection.h"
22#include "runtime.h"
23
24namespace art {
25namespace hiddenapi {
26
27// Returns true if member with `access flags` should only be accessed from
28// boot class path.
29inline bool IsMemberHidden(uint32_t access_flags) {
30 if (!Runtime::Current()->AreHiddenApiChecksEnabled()) {
31 return false;
32 }
33
34 switch (HiddenApiAccessFlags::DecodeFromRuntime(access_flags)) {
35 case HiddenApiAccessFlags::kWhitelist:
36 case HiddenApiAccessFlags::kLightGreylist:
37 case HiddenApiAccessFlags::kDarkGreylist:
38 return false;
39 case HiddenApiAccessFlags::kBlacklist:
40 return true;
41 }
42}
43
44// Returns true if caller `num_frames` up the stack is in boot class path.
45inline bool IsCallerInBootClassPath(Thread* self, size_t num_frames)
46 REQUIRES_SHARED(Locks::mutator_lock_) {
47 ObjPtr<mirror::Class> klass = GetCallingClass(self, num_frames);
48 if (klass == nullptr) {
49 // Unattached native thread. Assume that this is *not* boot class path.
50 return false;
51 }
52 return klass->IsBootStrapClassLoaded();
53}
54
55// Returns true if `caller` should not be allowed to access member with `access_flags`.
56inline bool ShouldBlockAccessToMember(uint32_t access_flags, mirror::Class* caller)
57 REQUIRES_SHARED(Locks::mutator_lock_) {
58 return IsMemberHidden(access_flags) &&
59 !caller->IsBootStrapClassLoaded();
60}
61
62// Returns true if `caller` should not be allowed to access `member`.
63template<typename T>
64inline bool ShouldBlockAccessToMember(T* member, ArtMethod* caller)
65 REQUIRES_SHARED(Locks::mutator_lock_) {
66 DCHECK(member != nullptr);
67 DCHECK(!caller->IsRuntimeMethod());
68 return ShouldBlockAccessToMember(member->GetAccessFlags(), caller->GetDeclaringClass());
69}
70
71// Returns true if the caller `num_frames` up the stack should not be allowed
72// to access `member`.
73template<typename T>
74inline bool ShouldBlockAccessToMember(T* member, Thread* self, size_t num_frames)
75 REQUIRES_SHARED(Locks::mutator_lock_) {
76 DCHECK(member != nullptr);
77 return IsMemberHidden(member->GetAccessFlags()) &&
78 !IsCallerInBootClassPath(self, num_frames); // This is expensive. Save it for last.
79}
80
81} // namespace hiddenapi
82} // namespace art
83
84#endif // ART_RUNTIME_HIDDEN_API_H_