blob: be6407963b93b7843aa8205298ad2cfd250584e5 [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>
20
21#include "base/file_utils.h"
David Brazdil2bb2fbd2018-11-13 18:24:26 +000022#include "base/sdk_version.h"
David Brazdila5c3a802019-03-08 14:59:41 +000023#include "base/stl_util.h"
Mathew Inwood7d74ef52018-03-16 14:18:33 +000024#include "common_runtime_test.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010025#include "jni/jni_internal.h"
David Brazdil1f9d3c32018-05-02 16:53:06 +010026#include "proxy_test.h"
David Brazdila5c3a802019-03-08 14:59:41 +000027#include "well_known_classes.h"
Mathew Inwood7d74ef52018-03-16 14:18:33 +000028
29namespace art {
30
Andreas Gampeaa120012018-03-28 16:23:24 -070031using hiddenapi::detail::MemberSignature;
David Brazdilf50ac102018-10-17 18:00:06 +010032using hiddenapi::detail::ShouldDenyAccessToMemberImpl;
Andreas Gampeaa120012018-03-28 16:23:24 -070033
Mathew Inwood7d74ef52018-03-16 14:18:33 +000034class HiddenApiTest : public CommonRuntimeTest {
35 protected:
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010036 void SetUp() override {
Mathew Inwood7d74ef52018-03-16 14:18:33 +000037 // Do the normal setup.
38 CommonRuntimeTest::SetUp();
39 self_ = Thread::Current();
40 self_->TransitionFromSuspendedToRunnable();
David Brazdil1f9d3c32018-05-02 16:53:06 +010041 jclass_loader_ = LoadDex("HiddenApiSignatures");
Mathew Inwood7d74ef52018-03-16 14:18:33 +000042 bool started = runtime_->Start();
43 CHECK(started);
44
45 class1_field1_ = getArtField("mypackage/packagea/Class1", "field1", "I");
46 class1_field12_ = getArtField("mypackage/packagea/Class1", "field12", "I");
47 class1_init_ = getArtMethod("mypackage/packagea/Class1", "<init>", "()V");
48 class1_method1_ = getArtMethod("mypackage/packagea/Class1", "method1", "()V");
49 class1_method1_i_ = getArtMethod("mypackage/packagea/Class1", "method1", "(I)V");
50 class1_method12_ = getArtMethod("mypackage/packagea/Class1", "method12", "()V");
51 class12_field1_ = getArtField("mypackage/packagea/Class12", "field1", "I");
52 class12_method1_ = getArtMethod("mypackage/packagea/Class12", "method1", "()V");
53 class2_field1_ = getArtField("mypackage/packagea/Class2", "field1", "I");
54 class2_method1_ = getArtMethod("mypackage/packagea/Class2", "method1", "()V");
55 class2_method1_i_ = getArtMethod("mypackage/packagea/Class2", "method1", "(I)V");
56 class3_field1_ = getArtField("mypackage/packageb/Class3", "field1", "I");
57 class3_method1_ = getArtMethod("mypackage/packageb/Class3", "method1", "()V");
58 class3_method1_i_ = getArtMethod("mypackage/packageb/Class3", "method1", "(I)V");
59 }
60
61 ArtMethod* getArtMethod(const char* class_name, const char* name, const char* signature) {
62 JNIEnv* env = Thread::Current()->GetJniEnv();
63 jclass klass = env->FindClass(class_name);
64 jmethodID method_id = env->GetMethodID(klass, name, signature);
65 ArtMethod* art_method = jni::DecodeArtMethod(method_id);
66 return art_method;
67 }
68
69 ArtField* getArtField(const char* class_name, const char* name, const char* signature) {
70 JNIEnv* env = Thread::Current()->GetJniEnv();
71 jclass klass = env->FindClass(class_name);
72 jfieldID field_id = env->GetFieldID(klass, name, signature);
73 ArtField* art_field = jni::DecodeArtField(field_id);
74 return art_field;
75 }
76
David Brazdilf50ac102018-10-17 18:00:06 +010077 bool ShouldDenyAccess(hiddenapi::ApiList list) REQUIRES_SHARED(Locks::mutator_lock_) {
78 // Choose parameters such that there are no side effects (AccessMethod::kNone)
79 // and that the member is not on the exemptions list (here we choose one which
80 // is not even in boot class path).
81 return ShouldDenyAccessToMemberImpl(/* member= */ class1_field1_,
82 list,
83 /* access_method= */ hiddenapi::AccessMethod::kNone);
84 }
85
Mathew Inwood7d74ef52018-03-16 14:18:33 +000086 protected:
87 Thread* self_;
David Brazdil1f9d3c32018-05-02 16:53:06 +010088 jobject jclass_loader_;
Mathew Inwood7d74ef52018-03-16 14:18:33 +000089 ArtField* class1_field1_;
90 ArtField* class1_field12_;
91 ArtMethod* class1_init_;
92 ArtMethod* class1_method1_;
93 ArtMethod* class1_method1_i_;
94 ArtMethod* class1_method12_;
95 ArtField* class12_field1_;
96 ArtMethod* class12_method1_;
97 ArtField* class2_field1_;
98 ArtMethod* class2_method1_;
99 ArtMethod* class2_method1_i_;
100 ArtField* class3_field1_;
101 ArtMethod* class3_method1_;
102 ArtMethod* class3_method1_i_;
103};
104
Mathew Inwooda8503d92018-04-05 16:10:25 +0100105TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
David Brazdilf50ac102018-10-17 18:00:06 +0100106 ScopedObjectAccess soa(self_);
107
Mathew Inwooda8503d92018-04-05 16:10:25 +0100108 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
David Brazdildcfa89b2018-10-31 11:04:10 +0000109 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
110 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000111 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000112 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
113 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), false);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100114
David Brazdilf50ac102018-10-17 18:00:06 +0100115 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000116 runtime_->SetTargetSdkVersion(
117 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()));
118 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
119 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000120 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000121 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
122 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100123
David Brazdilf50ac102018-10-17 18:00:06 +0100124 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000125 runtime_->SetTargetSdkVersion(
126 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()) + 1);
127 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
128 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000129 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
130 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
131 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
132
133 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
134 runtime_->SetTargetSdkVersion(
135 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxP().GetMaxAllowedSdkVersion()) + 1);
136 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
137 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
138 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), true);
David Brazdildcfa89b2018-10-31 11:04:10 +0000139 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
140 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100141}
142
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000143TEST_F(HiddenApiTest, CheckMembersRead) {
144 ASSERT_NE(nullptr, class1_field1_);
145 ASSERT_NE(nullptr, class1_field12_);
146 ASSERT_NE(nullptr, class1_init_);
147 ASSERT_NE(nullptr, class1_method1_);
148 ASSERT_NE(nullptr, class1_method1_i_);
149 ASSERT_NE(nullptr, class1_method12_);
150 ASSERT_NE(nullptr, class12_field1_);
151 ASSERT_NE(nullptr, class12_method1_);
152 ASSERT_NE(nullptr, class2_field1_);
153 ASSERT_NE(nullptr, class2_method1_);
154 ASSERT_NE(nullptr, class2_method1_i_);
155 ASSERT_NE(nullptr, class3_field1_);
156 ASSERT_NE(nullptr, class3_method1_);
157 ASSERT_NE(nullptr, class3_method1_i_);
158}
159
160TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
161 ScopedObjectAccess soa(self_);
162 std::string prefix("L");
Andreas Gampeaa120012018-03-28 16:23:24 -0700163 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
164 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
165 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
166 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
167 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
168 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
169 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
170 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
171 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
172 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
173 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
174 ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
175 ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
176 ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000177}
178
179TEST_F(HiddenApiTest, CheckPackageMatch) {
180 ScopedObjectAccess soa(self_);
181 std::string prefix("Lmypackage/packagea/");
Andreas Gampeaa120012018-03-28 16:23:24 -0700182 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
183 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
184 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
185 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
186 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
187 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
188 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
189 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
190 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
191 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
192 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
193 ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
194 ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
195 ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000196}
197
198TEST_F(HiddenApiTest, CheckClassMatch) {
199 ScopedObjectAccess soa(self_);
200 std::string prefix("Lmypackage/packagea/Class1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700201 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
202 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
203 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
204 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
205 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
206 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
207 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
208 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
209 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
210 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
211 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000212}
213
214TEST_F(HiddenApiTest, CheckClassExactMatch) {
215 ScopedObjectAccess soa(self_);
216 std::string prefix("Lmypackage/packagea/Class1;");
Andreas Gampeaa120012018-03-28 16:23:24 -0700217 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
218 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
219 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
220 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
221 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
222 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
223 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
224 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
225 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
226 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000227}
228
229TEST_F(HiddenApiTest, CheckMethodMatch) {
230 ScopedObjectAccess soa(self_);
231 std::string prefix("Lmypackage/packagea/Class1;->method1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700232 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
233 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
234 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
235 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
236 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
237 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
238 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
239 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000240}
241
242TEST_F(HiddenApiTest, CheckMethodExactMatch) {
243 ScopedObjectAccess soa(self_);
244 std::string prefix("Lmypackage/packagea/Class1;->method1(");
Andreas Gampeaa120012018-03-28 16:23:24 -0700245 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
246 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
247 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
248 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
249 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
250 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000251}
252
253TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
254 ScopedObjectAccess soa(self_);
255 std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
Andreas Gampeaa120012018-03-28 16:23:24 -0700256 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
257 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
258 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
259 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
260 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000261}
262
263TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
264 ScopedObjectAccess soa(self_);
265 std::string prefix("Lmypackage/packagea/Class1;->method1()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700266 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
267 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
268 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
269 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
270 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000271}
272
273TEST_F(HiddenApiTest, CheckFieldMatch) {
274 ScopedObjectAccess soa(self_);
275 std::string prefix("Lmypackage/packagea/Class1;->field1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700276 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
277 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
278 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
279 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
280 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000281}
282
283TEST_F(HiddenApiTest, CheckFieldExactMatch) {
284 ScopedObjectAccess soa(self_);
285 std::string prefix("Lmypackage/packagea/Class1;->field1:");
Andreas Gampeaa120012018-03-28 16:23:24 -0700286 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
287 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
288 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000289}
290
291TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
292 ScopedObjectAccess soa(self_);
293 std::string prefix("Lmypackage/packagea/Class1;->field1:I");
Andreas Gampeaa120012018-03-28 16:23:24 -0700294 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
295 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
296 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000297}
298
299TEST_F(HiddenApiTest, CheckConstructorMatch) {
300 ScopedObjectAccess soa(self_);
301 std::string prefix("Lmypackage/packagea/Class1;-><init>");
Andreas Gampeaa120012018-03-28 16:23:24 -0700302 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
303 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000304}
305
306TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
307 ScopedObjectAccess soa(self_);
308 std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700309 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
310 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000311}
312
313TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
314 ScopedObjectAccess soa(self_);
315 std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700316 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000317}
318
319TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
320 ScopedObjectAccess soa(self_);
321 std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700322 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000323}
324
325TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
326 ScopedObjectAccess soa(self_);
327 std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700328 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000329}
330
David Brazdil1f9d3c32018-05-02 16:53:06 +0100331TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
332 ScopedObjectAccess soa(self_);
333 StackHandleScope<4> hs(soa.Self());
334 Handle<mirror::ClassLoader> class_loader(
335 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
336
337 // Find interface we will create a proxy for.
338 Handle<mirror::Class> h_iface(hs.NewHandle(
339 class_linker_->FindClass(soa.Self(), "Lmypackage/packagea/Interface;", class_loader)));
340 ASSERT_TRUE(h_iface != nullptr);
341
342 // Create the proxy class.
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100343 std::vector<Handle<mirror::Class>> interfaces;
344 interfaces.push_back(h_iface);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100345 Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
346 soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
347 ASSERT_TRUE(proxyClass != nullptr);
348 ASSERT_TRUE(proxyClass->IsProxyClass());
349 ASSERT_TRUE(proxyClass->IsInitialized());
350
351 // Find the "method" virtual method.
352 ArtMethod* method = nullptr;
353 for (auto& m : proxyClass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
354 if (strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
355 method = &m;
356 break;
357 }
358 }
359 ASSERT_TRUE(method != nullptr);
360
361 // Find the "interfaces" static field. This is generated for all proxies.
362 ArtField* field = nullptr;
363 for (size_t i = 0; i < proxyClass->NumStaticFields(); ++i) {
364 ArtField* f = proxyClass->GetStaticField(i);
365 if (strcmp("interfaces", f->GetName()) == 0) {
366 field = f;
367 break;
368 }
369 }
370 ASSERT_TRUE(field != nullptr);
371
372 // Test the signature. We expect the signature from the interface class.
373 std::ostringstream ss_method;
David Brazdil6a1dab42019-02-28 18:45:15 +0000374 MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100375 ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());
376
377 // Test the signature. We expect the signature of the proxy class.
378 std::ostringstream ss_field;
379 MemberSignature(field).Dump(ss_field);
380 ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
381}
382
David Brazdila5c3a802019-03-08 14:59:41 +0000383static bool Copy(const std::string& src, const std::string& dst, /*out*/ std::string* error_msg) {
384 std::ifstream src_stream(src, std::ios::binary);
385 std::ofstream dst_stream(dst, std::ios::binary);
386 dst_stream << src_stream.rdbuf();
387 src_stream.close();
388 dst_stream.close();
389 if (src_stream.good() && dst_stream.good()) {
390 return true;
391 } else {
392 *error_msg = "Copy " + src + " => " + dst + " (src_good="
393 + (src_stream.good() ? "true" : "false") + ", dst_good="
394 + (dst_stream.good() ? "true" : "false") + ")";
395 return false;
396 }
397}
398
399static bool LoadDexFiles(const std::string& path,
400 ScopedObjectAccess& soa,
401 /* out */ std::vector<std::unique_ptr<const DexFile>>* dex_files,
402 /* out */ ObjPtr<mirror::ClassLoader>* class_loader,
403 /* out */ std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
404 if (!ArtDexFileLoader().Open(path.c_str(),
405 path,
406 /* verify= */ true,
407 /* verify_checksum= */ true,
408 error_msg,
409 dex_files)) {
410 return false;
411 }
412
413 ClassLinker* const linker = Runtime::Current()->GetClassLinker();
414
415 StackHandleScope<2> hs(soa.Self());
416 Handle<mirror::Class> h_class = hs.NewHandle(soa.Decode<mirror::Class>(
417 WellKnownClasses::dalvik_system_PathClassLoader));
418 Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader(
419 soa.Self(),
420 MakeNonOwningPointerVector(*dex_files),
421 h_class,
422 /* parent_loader= */ ScopedNullHandle<mirror::ClassLoader>(),
423 /* shared_libraries= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>()));
424 for (const auto& dex_file : *dex_files) {
425 linker->RegisterDexFile(*dex_file.get(), h_loader.Get());
426 }
427
428 *class_loader = h_loader.Get();
429 return true;
430}
431
432static bool CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,
433 const std::vector<std::unique_ptr<const DexFile>>& dex_files,
434 hiddenapi::Domain expected_domain)
435 REQUIRES_SHARED(Locks::mutator_lock_) {
436 for (const auto& dex_file : dex_files) {
437 hiddenapi::AccessContext context(loader, dex_file.get());
438 if (context.GetDomain() != expected_domain) {
439 LOG(ERROR) << dex_file->GetLocation() << ": access context domain does not match "
440 << "(expected=" << static_cast<uint32_t>(expected_domain)
441 << ", actual=" << static_cast<uint32_t>(context.GetDomain()) << ")";
442 return false;
443 }
444 if (dex_file->GetHiddenapiDomain() != expected_domain) {
445 LOG(ERROR) << dex_file->GetLocation() << ": dex file domain does not match "
446 << "(expected=" << static_cast<uint32_t>(expected_domain)
447 << ", actual=" << static_cast<uint32_t>(dex_file->GetHiddenapiDomain()) << ")";
448 return false;
449 }
450 }
451
452 return true;
453}
454
455TEST_F(HiddenApiTest, DexDomain_DataDir) {
456 // Load file from a non-system directory and check that it is not flagged as framework.
457 std::string data_location_path = android_data_ + "/foo.jar";
458 ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path.c_str()));
459
460 ScopedObjectAccess soa(Thread::Current());
461 std::vector<std::unique_ptr<const DexFile>> dex_files;
462 std::string error_msg;
463 ObjPtr<mirror::ClassLoader> class_loader;
464
465 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), data_location_path, &error_msg)) << error_msg;
466 ASSERT_TRUE(LoadDexFiles(data_location_path, soa, &dex_files, &class_loader, &error_msg))
467 << error_msg;
468 ASSERT_GE(dex_files.size(), 1u);
469 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader, dex_files, hiddenapi::Domain::kApplication));
470
471 dex_files.clear();
472 ASSERT_EQ(0, remove(data_location_path.c_str()));
473}
474
475TEST_F(HiddenApiTest, DexDomain_SystemDir) {
476 // Load file from a system, non-framework directory and check that it is not flagged as framework.
477 std::string system_location_path = GetAndroidRoot() + "/foo.jar";
478 ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path.c_str()));
479
480 ScopedObjectAccess soa(Thread::Current());
481 std::vector<std::unique_ptr<const DexFile>> dex_files;
482 std::string error_msg;
483 ObjPtr<mirror::ClassLoader> class_loader;
484
485 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_location_path, &error_msg)) << error_msg;
486 ASSERT_TRUE(LoadDexFiles(system_location_path, soa, &dex_files, &class_loader, &error_msg))
487 << error_msg;
488 ASSERT_GE(dex_files.size(), 1u);
489 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader, dex_files, hiddenapi::Domain::kApplication));
490
491 dex_files.clear();
492 ASSERT_EQ(0, remove(system_location_path.c_str()));
493}
494
495TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir) {
496 // Load file from a system/framework directory and check that it is flagged as a framework dex.
497 std::string system_framework_location_path = GetAndroidRoot() + "/framework/foo.jar";
498 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path.c_str()));
499
500 ScopedObjectAccess soa(Thread::Current());
501 std::vector<std::unique_ptr<const DexFile>> dex_files;
502 std::string error_msg;
503 ObjPtr<mirror::ClassLoader> class_loader;
504
505 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_framework_location_path, &error_msg))
506 << error_msg;
507 ASSERT_TRUE(LoadDexFiles(system_framework_location_path,
508 soa,
509 &dex_files,
510 &class_loader,
511 &error_msg)) << error_msg;
512 ASSERT_GE(dex_files.size(), 1u);
513 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader, dex_files, hiddenapi::Domain::kPlatform));
514
515 dex_files.clear();
516 ASSERT_EQ(0, remove(system_framework_location_path.c_str()));
517}
518
519TEST_F(HiddenApiTest, DexDomain_DataDir_MultiDex) {
520 // Load multidex file from a non-system directory and check that it is not flagged as framework.
521 std::string data_multi_location_path = android_data_ + "/multifoo.jar";
522 ASSERT_FALSE(LocationIsOnSystemFramework(data_multi_location_path.c_str()));
523
524 ScopedObjectAccess soa(Thread::Current());
525 std::vector<std::unique_ptr<const DexFile>> dex_files;
526 std::string error_msg;
527 ObjPtr<mirror::ClassLoader> class_loader;
528
529 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), data_multi_location_path, &error_msg))
530 << error_msg;
531 ASSERT_TRUE(LoadDexFiles(data_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
532 << error_msg;
533 ASSERT_GE(dex_files.size(), 1u);
534 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader, dex_files, hiddenapi::Domain::kApplication));
535
536 dex_files.clear();
537 ASSERT_EQ(0, remove(data_multi_location_path.c_str()));
538}
539
540TEST_F(HiddenApiTest, DexDomain_SystemDir_MultiDex) {
541 // Load multidex file from a system, non-framework directory and check that it is not flagged
542 // as framework.
543 std::string system_multi_location_path = GetAndroidRoot() + "/multifoo.jar";
544 ASSERT_FALSE(LocationIsOnSystemFramework(system_multi_location_path.c_str()));
545
546 ScopedObjectAccess soa(Thread::Current());
547 std::vector<std::unique_ptr<const DexFile>> dex_files;
548 std::string error_msg;
549 ObjPtr<mirror::ClassLoader> class_loader;
550
551 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), system_multi_location_path, &error_msg))
552 << error_msg;
553 ASSERT_TRUE(LoadDexFiles(system_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
554 << error_msg;
555 ASSERT_GT(dex_files.size(), 1u);
556 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader, dex_files, hiddenapi::Domain::kApplication));
557
558 dex_files.clear();
559 ASSERT_EQ(0, remove(system_multi_location_path.c_str()));
560}
561
562TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir_MultiDex) {
563 // Load multidex file from a system/framework directory and check that it is flagged as a
564 // framework dex.
565 std::string system_framework_multi_location_path = GetAndroidRoot() + "/framework/multifoo.jar";
566 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_multi_location_path.c_str()));
567
568 ScopedObjectAccess soa(Thread::Current());
569 std::vector<std::unique_ptr<const DexFile>> dex_files;
570 std::string error_msg;
571 ObjPtr<mirror::ClassLoader> class_loader;
572
573 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"),
574 system_framework_multi_location_path,
575 &error_msg)) << error_msg;
576 ASSERT_TRUE(LoadDexFiles(system_framework_multi_location_path,
577 soa,
578 &dex_files,
579 &class_loader,
580 &error_msg)) << error_msg;
581 ASSERT_GT(dex_files.size(), 1u);
582 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader, dex_files, hiddenapi::Domain::kPlatform));
583
584 dex_files.clear();
585 ASSERT_EQ(0, remove(system_framework_multi_location_path.c_str()));
586}
587
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000588} // namespace art