blob: 145bb076769802a05ad99a899ba90fb94132dfdb [file] [log] [blame]
Mathew Inwood7d74ef52018-03-16 14:18:33 +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#include "hidden_api.h"
18
David Brazdila5c3a802019-03-08 14:59:41 +000019#include <fstream>
David Brazdilbfaba282019-03-15 11:35:51 +000020#include <sstream>
David Brazdila5c3a802019-03-08 14:59:41 +000021
22#include "base/file_utils.h"
David Brazdil2bb2fbd2018-11-13 18:24:26 +000023#include "base/sdk_version.h"
David Brazdila5c3a802019-03-08 14:59:41 +000024#include "base/stl_util.h"
Mathew Inwood7d74ef52018-03-16 14:18:33 +000025#include "common_runtime_test.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010026#include "jni/jni_internal.h"
David Brazdil1f9d3c32018-05-02 16:53:06 +010027#include "proxy_test.h"
David Brazdila5c3a802019-03-08 14:59:41 +000028#include "well_known_classes.h"
Mathew Inwood7d74ef52018-03-16 14:18:33 +000029
30namespace art {
31
Andreas Gampeaa120012018-03-28 16:23:24 -070032using hiddenapi::detail::MemberSignature;
David Brazdilf50ac102018-10-17 18:00:06 +010033using hiddenapi::detail::ShouldDenyAccessToMemberImpl;
Andreas Gampeaa120012018-03-28 16:23:24 -070034
Mathew Inwood7d74ef52018-03-16 14:18:33 +000035class HiddenApiTest : public CommonRuntimeTest {
36 protected:
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010037 void SetUp() override {
Mathew Inwood7d74ef52018-03-16 14:18:33 +000038 // Do the normal setup.
39 CommonRuntimeTest::SetUp();
40 self_ = Thread::Current();
41 self_->TransitionFromSuspendedToRunnable();
David Brazdil1f9d3c32018-05-02 16:53:06 +010042 jclass_loader_ = LoadDex("HiddenApiSignatures");
Mathew Inwood7d74ef52018-03-16 14:18:33 +000043 bool started = runtime_->Start();
44 CHECK(started);
45
46 class1_field1_ = getArtField("mypackage/packagea/Class1", "field1", "I");
47 class1_field12_ = getArtField("mypackage/packagea/Class1", "field12", "I");
48 class1_init_ = getArtMethod("mypackage/packagea/Class1", "<init>", "()V");
49 class1_method1_ = getArtMethod("mypackage/packagea/Class1", "method1", "()V");
50 class1_method1_i_ = getArtMethod("mypackage/packagea/Class1", "method1", "(I)V");
51 class1_method12_ = getArtMethod("mypackage/packagea/Class1", "method12", "()V");
52 class12_field1_ = getArtField("mypackage/packagea/Class12", "field1", "I");
53 class12_method1_ = getArtMethod("mypackage/packagea/Class12", "method1", "()V");
54 class2_field1_ = getArtField("mypackage/packagea/Class2", "field1", "I");
55 class2_method1_ = getArtMethod("mypackage/packagea/Class2", "method1", "()V");
56 class2_method1_i_ = getArtMethod("mypackage/packagea/Class2", "method1", "(I)V");
57 class3_field1_ = getArtField("mypackage/packageb/Class3", "field1", "I");
58 class3_method1_ = getArtMethod("mypackage/packageb/Class3", "method1", "()V");
59 class3_method1_i_ = getArtMethod("mypackage/packageb/Class3", "method1", "(I)V");
60 }
61
62 ArtMethod* getArtMethod(const char* class_name, const char* name, const char* signature) {
63 JNIEnv* env = Thread::Current()->GetJniEnv();
64 jclass klass = env->FindClass(class_name);
65 jmethodID method_id = env->GetMethodID(klass, name, signature);
66 ArtMethod* art_method = jni::DecodeArtMethod(method_id);
67 return art_method;
68 }
69
70 ArtField* getArtField(const char* class_name, const char* name, const char* signature) {
71 JNIEnv* env = Thread::Current()->GetJniEnv();
72 jclass klass = env->FindClass(class_name);
73 jfieldID field_id = env->GetFieldID(klass, name, signature);
74 ArtField* art_field = jni::DecodeArtField(field_id);
75 return art_field;
76 }
77
David Brazdilf50ac102018-10-17 18:00:06 +010078 bool ShouldDenyAccess(hiddenapi::ApiList list) REQUIRES_SHARED(Locks::mutator_lock_) {
79 // Choose parameters such that there are no side effects (AccessMethod::kNone)
80 // and that the member is not on the exemptions list (here we choose one which
81 // is not even in boot class path).
82 return ShouldDenyAccessToMemberImpl(/* member= */ class1_field1_,
83 list,
84 /* access_method= */ hiddenapi::AccessMethod::kNone);
85 }
86
Mathew Inwood7d74ef52018-03-16 14:18:33 +000087 protected:
88 Thread* self_;
David Brazdil1f9d3c32018-05-02 16:53:06 +010089 jobject jclass_loader_;
Mathew Inwood7d74ef52018-03-16 14:18:33 +000090 ArtField* class1_field1_;
91 ArtField* class1_field12_;
92 ArtMethod* class1_init_;
93 ArtMethod* class1_method1_;
94 ArtMethod* class1_method1_i_;
95 ArtMethod* class1_method12_;
96 ArtField* class12_field1_;
97 ArtMethod* class12_method1_;
98 ArtField* class2_field1_;
99 ArtMethod* class2_method1_;
100 ArtMethod* class2_method1_i_;
101 ArtField* class3_field1_;
102 ArtMethod* class3_method1_;
103 ArtMethod* class3_method1_i_;
104};
105
Mathew Inwooda8503d92018-04-05 16:10:25 +0100106TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
David Brazdilf50ac102018-10-17 18:00:06 +0100107 ScopedObjectAccess soa(self_);
108
Mathew Inwooda8503d92018-04-05 16:10:25 +0100109 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
David Brazdildcfa89b2018-10-31 11:04:10 +0000110 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
111 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000112 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000113 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000114 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
115 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), false);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100116
David Brazdilf50ac102018-10-17 18:00:06 +0100117 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000118 runtime_->SetTargetSdkVersion(
119 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()));
120 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
121 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000122 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000123 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000124 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
125 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100126
David Brazdilf50ac102018-10-17 18:00:06 +0100127 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000128 runtime_->SetTargetSdkVersion(
129 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()) + 1);
130 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
131 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000132 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000133 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
134 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
135 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
136
137 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
138 runtime_->SetTargetSdkVersion(
139 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxP().GetMaxAllowedSdkVersion()) + 1);
140 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
141 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
Artur Satayev201ffea2019-10-31 14:58:03 +0000142 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), false);
143 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), true);
144 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
145 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
146
147 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
148 runtime_->SetTargetSdkVersion(
149 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxQ().GetMaxAllowedSdkVersion()) + 1);
150 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
151 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
152 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxQ()), true);
David Brazdil80d16282018-11-01 09:55:09 +0000153 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), true);
David Brazdildcfa89b2018-10-31 11:04:10 +0000154 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
155 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100156}
157
Artur Satayev267366c2019-10-31 14:59:26 +0000158TEST_F(HiddenApiTest, CheckTestApiEnforcement) {
159 ScopedObjectAccess soa(self_);
160
161 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
162 runtime_->SetTargetSdkVersion(
163 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxQ().GetMaxAllowedSdkVersion()) + 1);
164
165 // Default case where all TestApis are treated like non-TestApi.
166 runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
167 ASSERT_EQ(
168 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Whitelist()), false);
169 ASSERT_EQ(
170 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Greylist()), false);
171 ASSERT_EQ(
172 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxQ()), true);
173 ASSERT_EQ(
174 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxP()), true);
175 ASSERT_EQ(
176 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxO()), true);
177 ASSERT_EQ(
178 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Blacklist()), true);
179
180 // A case where we want to allow access to TestApis.
181 runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kDisabled);
182 ASSERT_EQ(
183 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Whitelist()), false);
184 ASSERT_EQ(
185 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Greylist()), false);
186 ASSERT_EQ(
187 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxQ()), false);
188 ASSERT_EQ(
189 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxP()), false);
190 ASSERT_EQ(
191 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::GreylistMaxO()), false);
192 ASSERT_EQ(
193 ShouldDenyAccess(hiddenapi::ApiList::TestApi() | hiddenapi::ApiList::Blacklist()), false);
194}
195
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000196TEST_F(HiddenApiTest, CheckMembersRead) {
197 ASSERT_NE(nullptr, class1_field1_);
198 ASSERT_NE(nullptr, class1_field12_);
199 ASSERT_NE(nullptr, class1_init_);
200 ASSERT_NE(nullptr, class1_method1_);
201 ASSERT_NE(nullptr, class1_method1_i_);
202 ASSERT_NE(nullptr, class1_method12_);
203 ASSERT_NE(nullptr, class12_field1_);
204 ASSERT_NE(nullptr, class12_method1_);
205 ASSERT_NE(nullptr, class2_field1_);
206 ASSERT_NE(nullptr, class2_method1_);
207 ASSERT_NE(nullptr, class2_method1_i_);
208 ASSERT_NE(nullptr, class3_field1_);
209 ASSERT_NE(nullptr, class3_method1_);
210 ASSERT_NE(nullptr, class3_method1_i_);
211}
212
213TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
214 ScopedObjectAccess soa(self_);
215 std::string prefix("L");
Andreas Gampeaa120012018-03-28 16:23:24 -0700216 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
217 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
218 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
219 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
220 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
221 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
222 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
223 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
224 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
225 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
226 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
227 ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
228 ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
229 ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000230}
231
232TEST_F(HiddenApiTest, CheckPackageMatch) {
233 ScopedObjectAccess soa(self_);
234 std::string prefix("Lmypackage/packagea/");
Andreas Gampeaa120012018-03-28 16:23:24 -0700235 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
236 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
237 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
238 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
239 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
240 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
241 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
242 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
243 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
244 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
245 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
246 ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
247 ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
248 ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000249}
250
251TEST_F(HiddenApiTest, CheckClassMatch) {
252 ScopedObjectAccess soa(self_);
253 std::string prefix("Lmypackage/packagea/Class1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700254 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
255 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
256 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
257 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
258 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
259 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
260 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
261 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
262 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
263 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
264 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000265}
266
267TEST_F(HiddenApiTest, CheckClassExactMatch) {
268 ScopedObjectAccess soa(self_);
269 std::string prefix("Lmypackage/packagea/Class1;");
Andreas Gampeaa120012018-03-28 16:23:24 -0700270 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
271 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
272 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
273 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
274 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
275 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
276 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
277 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
278 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
279 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000280}
281
282TEST_F(HiddenApiTest, CheckMethodMatch) {
283 ScopedObjectAccess soa(self_);
284 std::string prefix("Lmypackage/packagea/Class1;->method1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700285 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
286 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
287 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
288 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
289 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
290 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
291 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
292 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000293}
294
295TEST_F(HiddenApiTest, CheckMethodExactMatch) {
296 ScopedObjectAccess soa(self_);
297 std::string prefix("Lmypackage/packagea/Class1;->method1(");
Andreas Gampeaa120012018-03-28 16:23:24 -0700298 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
299 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
300 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
301 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
302 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
303 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000304}
305
306TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
307 ScopedObjectAccess soa(self_);
308 std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
Andreas Gampeaa120012018-03-28 16:23:24 -0700309 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
310 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
311 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
312 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
313 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000314}
315
316TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
317 ScopedObjectAccess soa(self_);
318 std::string prefix("Lmypackage/packagea/Class1;->method1()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700319 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
320 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
321 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
322 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
323 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000324}
325
326TEST_F(HiddenApiTest, CheckFieldMatch) {
327 ScopedObjectAccess soa(self_);
328 std::string prefix("Lmypackage/packagea/Class1;->field1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700329 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
330 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
331 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
332 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
333 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000334}
335
336TEST_F(HiddenApiTest, CheckFieldExactMatch) {
337 ScopedObjectAccess soa(self_);
338 std::string prefix("Lmypackage/packagea/Class1;->field1:");
Andreas Gampeaa120012018-03-28 16:23:24 -0700339 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
340 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
341 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000342}
343
344TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
345 ScopedObjectAccess soa(self_);
346 std::string prefix("Lmypackage/packagea/Class1;->field1:I");
Andreas Gampeaa120012018-03-28 16:23:24 -0700347 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
348 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
349 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000350}
351
352TEST_F(HiddenApiTest, CheckConstructorMatch) {
353 ScopedObjectAccess soa(self_);
354 std::string prefix("Lmypackage/packagea/Class1;-><init>");
Andreas Gampeaa120012018-03-28 16:23:24 -0700355 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
356 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000357}
358
359TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
360 ScopedObjectAccess soa(self_);
361 std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700362 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
363 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000364}
365
366TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
367 ScopedObjectAccess soa(self_);
368 std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700369 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000370}
371
372TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
373 ScopedObjectAccess soa(self_);
374 std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700375 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000376}
377
378TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
379 ScopedObjectAccess soa(self_);
380 std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700381 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000382}
383
David Brazdil1f9d3c32018-05-02 16:53:06 +0100384TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
385 ScopedObjectAccess soa(self_);
386 StackHandleScope<4> hs(soa.Self());
387 Handle<mirror::ClassLoader> class_loader(
388 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
389
390 // Find interface we will create a proxy for.
391 Handle<mirror::Class> h_iface(hs.NewHandle(
392 class_linker_->FindClass(soa.Self(), "Lmypackage/packagea/Interface;", class_loader)));
393 ASSERT_TRUE(h_iface != nullptr);
394
395 // Create the proxy class.
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100396 std::vector<Handle<mirror::Class>> interfaces;
397 interfaces.push_back(h_iface);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100398 Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
399 soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
400 ASSERT_TRUE(proxyClass != nullptr);
401 ASSERT_TRUE(proxyClass->IsProxyClass());
402 ASSERT_TRUE(proxyClass->IsInitialized());
403
404 // Find the "method" virtual method.
405 ArtMethod* method = nullptr;
406 for (auto& m : proxyClass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
407 if (strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
408 method = &m;
409 break;
410 }
411 }
412 ASSERT_TRUE(method != nullptr);
413
414 // Find the "interfaces" static field. This is generated for all proxies.
415 ArtField* field = nullptr;
416 for (size_t i = 0; i < proxyClass->NumStaticFields(); ++i) {
417 ArtField* f = proxyClass->GetStaticField(i);
418 if (strcmp("interfaces", f->GetName()) == 0) {
419 field = f;
420 break;
421 }
422 }
423 ASSERT_TRUE(field != nullptr);
424
425 // Test the signature. We expect the signature from the interface class.
426 std::ostringstream ss_method;
David Brazdil6a1dab42019-02-28 18:45:15 +0000427 MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100428 ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());
429
430 // Test the signature. We expect the signature of the proxy class.
431 std::ostringstream ss_field;
432 MemberSignature(field).Dump(ss_field);
433 ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
434}
435
David Brazdila5c3a802019-03-08 14:59:41 +0000436static bool Copy(const std::string& src, const std::string& dst, /*out*/ std::string* error_msg) {
437 std::ifstream src_stream(src, std::ios::binary);
438 std::ofstream dst_stream(dst, std::ios::binary);
439 dst_stream << src_stream.rdbuf();
440 src_stream.close();
441 dst_stream.close();
442 if (src_stream.good() && dst_stream.good()) {
443 return true;
444 } else {
445 *error_msg = "Copy " + src + " => " + dst + " (src_good="
446 + (src_stream.good() ? "true" : "false") + ", dst_good="
447 + (dst_stream.good() ? "true" : "false") + ")";
448 return false;
449 }
450}
451
452static bool LoadDexFiles(const std::string& path,
453 ScopedObjectAccess& soa,
454 /* out */ std::vector<std::unique_ptr<const DexFile>>* dex_files,
455 /* out */ ObjPtr<mirror::ClassLoader>* class_loader,
456 /* out */ std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
457 if (!ArtDexFileLoader().Open(path.c_str(),
458 path,
459 /* verify= */ true,
460 /* verify_checksum= */ true,
461 error_msg,
462 dex_files)) {
463 return false;
464 }
465
466 ClassLinker* const linker = Runtime::Current()->GetClassLinker();
467
468 StackHandleScope<2> hs(soa.Self());
469 Handle<mirror::Class> h_class = hs.NewHandle(soa.Decode<mirror::Class>(
470 WellKnownClasses::dalvik_system_PathClassLoader));
471 Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader(
472 soa.Self(),
473 MakeNonOwningPointerVector(*dex_files),
474 h_class,
475 /* parent_loader= */ ScopedNullHandle<mirror::ClassLoader>(),
476 /* shared_libraries= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>()));
477 for (const auto& dex_file : *dex_files) {
478 linker->RegisterDexFile(*dex_file.get(), h_loader.Get());
479 }
480
481 *class_loader = h_loader.Get();
482 return true;
483}
484
485static bool CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,
486 const std::vector<std::unique_ptr<const DexFile>>& dex_files,
David Brazdilbfaba282019-03-15 11:35:51 +0000487 hiddenapi::Domain expected_domain,
488 /* out */ std::string* error_msg)
David Brazdila5c3a802019-03-08 14:59:41 +0000489 REQUIRES_SHARED(Locks::mutator_lock_) {
490 for (const auto& dex_file : dex_files) {
491 hiddenapi::AccessContext context(loader, dex_file.get());
492 if (context.GetDomain() != expected_domain) {
David Brazdilbfaba282019-03-15 11:35:51 +0000493 std::stringstream ss;
494 ss << dex_file->GetLocation() << ": access context domain does not match "
David Brazdila5c3a802019-03-08 14:59:41 +0000495 << "(expected=" << static_cast<uint32_t>(expected_domain)
496 << ", actual=" << static_cast<uint32_t>(context.GetDomain()) << ")";
David Brazdilbfaba282019-03-15 11:35:51 +0000497 *error_msg = ss.str();
David Brazdila5c3a802019-03-08 14:59:41 +0000498 return false;
499 }
500 if (dex_file->GetHiddenapiDomain() != expected_domain) {
David Brazdilbfaba282019-03-15 11:35:51 +0000501 std::stringstream ss;
502 ss << dex_file->GetLocation() << ": dex file domain does not match "
David Brazdila5c3a802019-03-08 14:59:41 +0000503 << "(expected=" << static_cast<uint32_t>(expected_domain)
504 << ", actual=" << static_cast<uint32_t>(dex_file->GetHiddenapiDomain()) << ")";
David Brazdilbfaba282019-03-15 11:35:51 +0000505 *error_msg = ss.str();
David Brazdila5c3a802019-03-08 14:59:41 +0000506 return false;
507 }
508 }
509
510 return true;
511}
512
513TEST_F(HiddenApiTest, DexDomain_DataDir) {
514 // Load file from a non-system directory and check that it is not flagged as framework.
515 std::string data_location_path = android_data_ + "/foo.jar";
516 ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path.c_str()));
517
518 ScopedObjectAccess soa(Thread::Current());
519 std::vector<std::unique_ptr<const DexFile>> dex_files;
520 std::string error_msg;
521 ObjPtr<mirror::ClassLoader> class_loader;
522
523 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), data_location_path, &error_msg)) << error_msg;
524 ASSERT_TRUE(LoadDexFiles(data_location_path, soa, &dex_files, &class_loader, &error_msg))
525 << error_msg;
526 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000527 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
528 dex_files,
529 hiddenapi::Domain::kApplication,
530 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000531
532 dex_files.clear();
533 ASSERT_EQ(0, remove(data_location_path.c_str()));
534}
535
536TEST_F(HiddenApiTest, DexDomain_SystemDir) {
537 // Load file from a system, non-framework directory and check that it is not flagged as framework.
538 std::string system_location_path = GetAndroidRoot() + "/foo.jar";
539 ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path.c_str()));
540
541 ScopedObjectAccess soa(Thread::Current());
542 std::vector<std::unique_ptr<const DexFile>> dex_files;
543 std::string error_msg;
544 ObjPtr<mirror::ClassLoader> class_loader;
545
546 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_location_path, &error_msg)) << error_msg;
547 ASSERT_TRUE(LoadDexFiles(system_location_path, soa, &dex_files, &class_loader, &error_msg))
548 << error_msg;
549 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000550 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
551 dex_files,
552 hiddenapi::Domain::kApplication,
553 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000554
555 dex_files.clear();
556 ASSERT_EQ(0, remove(system_location_path.c_str()));
557}
558
559TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir) {
560 // Load file from a system/framework directory and check that it is flagged as a framework dex.
561 std::string system_framework_location_path = GetAndroidRoot() + "/framework/foo.jar";
562 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path.c_str()));
563
564 ScopedObjectAccess soa(Thread::Current());
565 std::vector<std::unique_ptr<const DexFile>> dex_files;
566 std::string error_msg;
567 ObjPtr<mirror::ClassLoader> class_loader;
568
569 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_framework_location_path, &error_msg))
570 << error_msg;
571 ASSERT_TRUE(LoadDexFiles(system_framework_location_path,
572 soa,
573 &dex_files,
574 &class_loader,
575 &error_msg)) << error_msg;
576 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000577 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
578 dex_files,
579 hiddenapi::Domain::kPlatform,
580 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000581
582 dex_files.clear();
583 ASSERT_EQ(0, remove(system_framework_location_path.c_str()));
584}
585
586TEST_F(HiddenApiTest, DexDomain_DataDir_MultiDex) {
587 // Load multidex file from a non-system directory and check that it is not flagged as framework.
588 std::string data_multi_location_path = android_data_ + "/multifoo.jar";
589 ASSERT_FALSE(LocationIsOnSystemFramework(data_multi_location_path.c_str()));
590
591 ScopedObjectAccess soa(Thread::Current());
592 std::vector<std::unique_ptr<const DexFile>> dex_files;
593 std::string error_msg;
594 ObjPtr<mirror::ClassLoader> class_loader;
595
596 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), data_multi_location_path, &error_msg))
597 << error_msg;
598 ASSERT_TRUE(LoadDexFiles(data_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
599 << error_msg;
600 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000601 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
602 dex_files,
603 hiddenapi::Domain::kApplication,
604 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000605
606 dex_files.clear();
607 ASSERT_EQ(0, remove(data_multi_location_path.c_str()));
608}
609
610TEST_F(HiddenApiTest, DexDomain_SystemDir_MultiDex) {
611 // Load multidex file from a system, non-framework directory and check that it is not flagged
612 // as framework.
613 std::string system_multi_location_path = GetAndroidRoot() + "/multifoo.jar";
614 ASSERT_FALSE(LocationIsOnSystemFramework(system_multi_location_path.c_str()));
615
616 ScopedObjectAccess soa(Thread::Current());
617 std::vector<std::unique_ptr<const DexFile>> dex_files;
618 std::string error_msg;
619 ObjPtr<mirror::ClassLoader> class_loader;
620
621 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), system_multi_location_path, &error_msg))
622 << error_msg;
623 ASSERT_TRUE(LoadDexFiles(system_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
624 << error_msg;
625 ASSERT_GT(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000626 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
627 dex_files,
628 hiddenapi::Domain::kApplication,
629 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000630
631 dex_files.clear();
632 ASSERT_EQ(0, remove(system_multi_location_path.c_str()));
633}
634
635TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir_MultiDex) {
636 // Load multidex file from a system/framework directory and check that it is flagged as a
637 // framework dex.
638 std::string system_framework_multi_location_path = GetAndroidRoot() + "/framework/multifoo.jar";
639 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_multi_location_path.c_str()));
640
641 ScopedObjectAccess soa(Thread::Current());
642 std::vector<std::unique_ptr<const DexFile>> dex_files;
643 std::string error_msg;
644 ObjPtr<mirror::ClassLoader> class_loader;
645
646 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"),
647 system_framework_multi_location_path,
648 &error_msg)) << error_msg;
649 ASSERT_TRUE(LoadDexFiles(system_framework_multi_location_path,
650 soa,
651 &dex_files,
652 &class_loader,
653 &error_msg)) << error_msg;
654 ASSERT_GT(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000655 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
656 dex_files,
657 hiddenapi::Domain::kPlatform,
658 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000659
660 dex_files.clear();
661 ASSERT_EQ(0, remove(system_framework_multi_location_path.c_str()));
662}
663
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000664} // namespace art