blob: 70fafe658786e8d940672bf959f5c384b0c1e9fb [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);
David Brazdil80d16282018-11-01 09:55:09 +0000112 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000113 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
114 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), false);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100115
David Brazdilf50ac102018-10-17 18:00:06 +0100116 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000117 runtime_->SetTargetSdkVersion(
118 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()));
119 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
120 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000121 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
David Brazdildcfa89b2018-10-31 11:04:10 +0000122 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
123 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100124
David Brazdilf50ac102018-10-17 18:00:06 +0100125 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
David Brazdildcfa89b2018-10-31 11:04:10 +0000126 runtime_->SetTargetSdkVersion(
127 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxO().GetMaxAllowedSdkVersion()) + 1);
128 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
129 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
David Brazdil80d16282018-11-01 09:55:09 +0000130 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
131 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
132 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
133
134 runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
135 runtime_->SetTargetSdkVersion(
136 static_cast<uint32_t>(hiddenapi::ApiList::GreylistMaxP().GetMaxAllowedSdkVersion()) + 1);
137 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
138 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
139 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), true);
David Brazdildcfa89b2018-10-31 11:04:10 +0000140 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
141 ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
Mathew Inwooda8503d92018-04-05 16:10:25 +0100142}
143
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000144TEST_F(HiddenApiTest, CheckMembersRead) {
145 ASSERT_NE(nullptr, class1_field1_);
146 ASSERT_NE(nullptr, class1_field12_);
147 ASSERT_NE(nullptr, class1_init_);
148 ASSERT_NE(nullptr, class1_method1_);
149 ASSERT_NE(nullptr, class1_method1_i_);
150 ASSERT_NE(nullptr, class1_method12_);
151 ASSERT_NE(nullptr, class12_field1_);
152 ASSERT_NE(nullptr, class12_method1_);
153 ASSERT_NE(nullptr, class2_field1_);
154 ASSERT_NE(nullptr, class2_method1_);
155 ASSERT_NE(nullptr, class2_method1_i_);
156 ASSERT_NE(nullptr, class3_field1_);
157 ASSERT_NE(nullptr, class3_method1_);
158 ASSERT_NE(nullptr, class3_method1_i_);
159}
160
161TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
162 ScopedObjectAccess soa(self_);
163 std::string prefix("L");
Andreas Gampeaa120012018-03-28 16:23:24 -0700164 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
165 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
166 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
167 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
168 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
169 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
170 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
171 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
172 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
173 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
174 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
175 ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
176 ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
177 ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000178}
179
180TEST_F(HiddenApiTest, CheckPackageMatch) {
181 ScopedObjectAccess soa(self_);
182 std::string prefix("Lmypackage/packagea/");
Andreas Gampeaa120012018-03-28 16:23:24 -0700183 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
184 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
185 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
186 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
187 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
188 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
189 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
190 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
191 ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
192 ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
193 ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
194 ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
195 ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
196 ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000197}
198
199TEST_F(HiddenApiTest, CheckClassMatch) {
200 ScopedObjectAccess soa(self_);
201 std::string prefix("Lmypackage/packagea/Class1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700202 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
203 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
204 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
205 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
206 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
207 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
208 ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
209 ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
210 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
211 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
212 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000213}
214
215TEST_F(HiddenApiTest, CheckClassExactMatch) {
216 ScopedObjectAccess soa(self_);
217 std::string prefix("Lmypackage/packagea/Class1;");
Andreas Gampeaa120012018-03-28 16:23:24 -0700218 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
219 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
220 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
221 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
222 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
223 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
224 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
225 ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
226 ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
227 ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000228}
229
230TEST_F(HiddenApiTest, CheckMethodMatch) {
231 ScopedObjectAccess soa(self_);
232 std::string prefix("Lmypackage/packagea/Class1;->method1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700233 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
234 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
235 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
236 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
237 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
238 ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
239 ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
240 ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000241}
242
243TEST_F(HiddenApiTest, CheckMethodExactMatch) {
244 ScopedObjectAccess soa(self_);
245 std::string prefix("Lmypackage/packagea/Class1;->method1(");
Andreas Gampeaa120012018-03-28 16:23:24 -0700246 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
247 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
248 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
249 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
250 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
251 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000252}
253
254TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
255 ScopedObjectAccess soa(self_);
256 std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
Andreas Gampeaa120012018-03-28 16:23:24 -0700257 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
258 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
259 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
260 ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
261 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000262}
263
264TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
265 ScopedObjectAccess soa(self_);
266 std::string prefix("Lmypackage/packagea/Class1;->method1()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700267 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
268 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
269 ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
270 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
271 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000272}
273
274TEST_F(HiddenApiTest, CheckFieldMatch) {
275 ScopedObjectAccess soa(self_);
276 std::string prefix("Lmypackage/packagea/Class1;->field1");
Andreas Gampeaa120012018-03-28 16:23:24 -0700277 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
278 ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
279 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
280 ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
281 ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000282}
283
284TEST_F(HiddenApiTest, CheckFieldExactMatch) {
285 ScopedObjectAccess soa(self_);
286 std::string prefix("Lmypackage/packagea/Class1;->field1:");
Andreas Gampeaa120012018-03-28 16:23:24 -0700287 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
288 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
289 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000290}
291
292TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
293 ScopedObjectAccess soa(self_);
294 std::string prefix("Lmypackage/packagea/Class1;->field1:I");
Andreas Gampeaa120012018-03-28 16:23:24 -0700295 ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
296 ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
297 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000298}
299
300TEST_F(HiddenApiTest, CheckConstructorMatch) {
301 ScopedObjectAccess soa(self_);
302 std::string prefix("Lmypackage/packagea/Class1;-><init>");
Andreas Gampeaa120012018-03-28 16:23:24 -0700303 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
304 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000305}
306
307TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
308 ScopedObjectAccess soa(self_);
309 std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
Andreas Gampeaa120012018-03-28 16:23:24 -0700310 ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
311 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000312}
313
314TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
315 ScopedObjectAccess soa(self_);
316 std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700317 ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000318}
319
320TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
321 ScopedObjectAccess soa(self_);
322 std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700323 ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000324}
325
326TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
327 ScopedObjectAccess soa(self_);
328 std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
Andreas Gampeaa120012018-03-28 16:23:24 -0700329 ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000330}
331
David Brazdil1f9d3c32018-05-02 16:53:06 +0100332TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
333 ScopedObjectAccess soa(self_);
334 StackHandleScope<4> hs(soa.Self());
335 Handle<mirror::ClassLoader> class_loader(
336 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
337
338 // Find interface we will create a proxy for.
339 Handle<mirror::Class> h_iface(hs.NewHandle(
340 class_linker_->FindClass(soa.Self(), "Lmypackage/packagea/Interface;", class_loader)));
341 ASSERT_TRUE(h_iface != nullptr);
342
343 // Create the proxy class.
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100344 std::vector<Handle<mirror::Class>> interfaces;
345 interfaces.push_back(h_iface);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100346 Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
347 soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
348 ASSERT_TRUE(proxyClass != nullptr);
349 ASSERT_TRUE(proxyClass->IsProxyClass());
350 ASSERT_TRUE(proxyClass->IsInitialized());
351
352 // Find the "method" virtual method.
353 ArtMethod* method = nullptr;
354 for (auto& m : proxyClass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
355 if (strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
356 method = &m;
357 break;
358 }
359 }
360 ASSERT_TRUE(method != nullptr);
361
362 // Find the "interfaces" static field. This is generated for all proxies.
363 ArtField* field = nullptr;
364 for (size_t i = 0; i < proxyClass->NumStaticFields(); ++i) {
365 ArtField* f = proxyClass->GetStaticField(i);
366 if (strcmp("interfaces", f->GetName()) == 0) {
367 field = f;
368 break;
369 }
370 }
371 ASSERT_TRUE(field != nullptr);
372
373 // Test the signature. We expect the signature from the interface class.
374 std::ostringstream ss_method;
David Brazdil6a1dab42019-02-28 18:45:15 +0000375 MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
David Brazdil1f9d3c32018-05-02 16:53:06 +0100376 ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());
377
378 // Test the signature. We expect the signature of the proxy class.
379 std::ostringstream ss_field;
380 MemberSignature(field).Dump(ss_field);
381 ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
382}
383
David Brazdila5c3a802019-03-08 14:59:41 +0000384static bool Copy(const std::string& src, const std::string& dst, /*out*/ std::string* error_msg) {
385 std::ifstream src_stream(src, std::ios::binary);
386 std::ofstream dst_stream(dst, std::ios::binary);
387 dst_stream << src_stream.rdbuf();
388 src_stream.close();
389 dst_stream.close();
390 if (src_stream.good() && dst_stream.good()) {
391 return true;
392 } else {
393 *error_msg = "Copy " + src + " => " + dst + " (src_good="
394 + (src_stream.good() ? "true" : "false") + ", dst_good="
395 + (dst_stream.good() ? "true" : "false") + ")";
396 return false;
397 }
398}
399
400static bool LoadDexFiles(const std::string& path,
401 ScopedObjectAccess& soa,
402 /* out */ std::vector<std::unique_ptr<const DexFile>>* dex_files,
403 /* out */ ObjPtr<mirror::ClassLoader>* class_loader,
404 /* out */ std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
405 if (!ArtDexFileLoader().Open(path.c_str(),
406 path,
407 /* verify= */ true,
408 /* verify_checksum= */ true,
409 error_msg,
410 dex_files)) {
411 return false;
412 }
413
414 ClassLinker* const linker = Runtime::Current()->GetClassLinker();
415
416 StackHandleScope<2> hs(soa.Self());
417 Handle<mirror::Class> h_class = hs.NewHandle(soa.Decode<mirror::Class>(
418 WellKnownClasses::dalvik_system_PathClassLoader));
419 Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader(
420 soa.Self(),
421 MakeNonOwningPointerVector(*dex_files),
422 h_class,
423 /* parent_loader= */ ScopedNullHandle<mirror::ClassLoader>(),
424 /* shared_libraries= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>()));
425 for (const auto& dex_file : *dex_files) {
426 linker->RegisterDexFile(*dex_file.get(), h_loader.Get());
427 }
428
429 *class_loader = h_loader.Get();
430 return true;
431}
432
433static bool CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,
434 const std::vector<std::unique_ptr<const DexFile>>& dex_files,
David Brazdilbfaba282019-03-15 11:35:51 +0000435 hiddenapi::Domain expected_domain,
436 /* out */ std::string* error_msg)
David Brazdila5c3a802019-03-08 14:59:41 +0000437 REQUIRES_SHARED(Locks::mutator_lock_) {
438 for (const auto& dex_file : dex_files) {
439 hiddenapi::AccessContext context(loader, dex_file.get());
440 if (context.GetDomain() != expected_domain) {
David Brazdilbfaba282019-03-15 11:35:51 +0000441 std::stringstream ss;
442 ss << dex_file->GetLocation() << ": access context domain does not match "
David Brazdila5c3a802019-03-08 14:59:41 +0000443 << "(expected=" << static_cast<uint32_t>(expected_domain)
444 << ", actual=" << static_cast<uint32_t>(context.GetDomain()) << ")";
David Brazdilbfaba282019-03-15 11:35:51 +0000445 *error_msg = ss.str();
David Brazdila5c3a802019-03-08 14:59:41 +0000446 return false;
447 }
448 if (dex_file->GetHiddenapiDomain() != expected_domain) {
David Brazdilbfaba282019-03-15 11:35:51 +0000449 std::stringstream ss;
450 ss << dex_file->GetLocation() << ": dex file domain does not match "
David Brazdila5c3a802019-03-08 14:59:41 +0000451 << "(expected=" << static_cast<uint32_t>(expected_domain)
452 << ", actual=" << static_cast<uint32_t>(dex_file->GetHiddenapiDomain()) << ")";
David Brazdilbfaba282019-03-15 11:35:51 +0000453 *error_msg = ss.str();
David Brazdila5c3a802019-03-08 14:59:41 +0000454 return false;
455 }
456 }
457
458 return true;
459}
460
461TEST_F(HiddenApiTest, DexDomain_DataDir) {
462 // Load file from a non-system directory and check that it is not flagged as framework.
463 std::string data_location_path = android_data_ + "/foo.jar";
464 ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path.c_str()));
465
466 ScopedObjectAccess soa(Thread::Current());
467 std::vector<std::unique_ptr<const DexFile>> dex_files;
468 std::string error_msg;
469 ObjPtr<mirror::ClassLoader> class_loader;
470
471 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), data_location_path, &error_msg)) << error_msg;
472 ASSERT_TRUE(LoadDexFiles(data_location_path, soa, &dex_files, &class_loader, &error_msg))
473 << error_msg;
474 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000475 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
476 dex_files,
477 hiddenapi::Domain::kApplication,
478 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000479
480 dex_files.clear();
481 ASSERT_EQ(0, remove(data_location_path.c_str()));
482}
483
484TEST_F(HiddenApiTest, DexDomain_SystemDir) {
485 // Load file from a system, non-framework directory and check that it is not flagged as framework.
486 std::string system_location_path = GetAndroidRoot() + "/foo.jar";
487 ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path.c_str()));
488
489 ScopedObjectAccess soa(Thread::Current());
490 std::vector<std::unique_ptr<const DexFile>> dex_files;
491 std::string error_msg;
492 ObjPtr<mirror::ClassLoader> class_loader;
493
494 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_location_path, &error_msg)) << error_msg;
495 ASSERT_TRUE(LoadDexFiles(system_location_path, soa, &dex_files, &class_loader, &error_msg))
496 << error_msg;
497 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000498 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
499 dex_files,
500 hiddenapi::Domain::kApplication,
501 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000502
503 dex_files.clear();
504 ASSERT_EQ(0, remove(system_location_path.c_str()));
505}
506
507TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir) {
508 // Load file from a system/framework directory and check that it is flagged as a framework dex.
509 std::string system_framework_location_path = GetAndroidRoot() + "/framework/foo.jar";
510 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path.c_str()));
511
512 ScopedObjectAccess soa(Thread::Current());
513 std::vector<std::unique_ptr<const DexFile>> dex_files;
514 std::string error_msg;
515 ObjPtr<mirror::ClassLoader> class_loader;
516
517 ASSERT_TRUE(Copy(GetTestDexFileName("Main"), system_framework_location_path, &error_msg))
518 << error_msg;
519 ASSERT_TRUE(LoadDexFiles(system_framework_location_path,
520 soa,
521 &dex_files,
522 &class_loader,
523 &error_msg)) << error_msg;
524 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000525 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
526 dex_files,
527 hiddenapi::Domain::kPlatform,
528 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000529
530 dex_files.clear();
531 ASSERT_EQ(0, remove(system_framework_location_path.c_str()));
532}
533
534TEST_F(HiddenApiTest, DexDomain_DataDir_MultiDex) {
535 // Load multidex file from a non-system directory and check that it is not flagged as framework.
536 std::string data_multi_location_path = android_data_ + "/multifoo.jar";
537 ASSERT_FALSE(LocationIsOnSystemFramework(data_multi_location_path.c_str()));
538
539 ScopedObjectAccess soa(Thread::Current());
540 std::vector<std::unique_ptr<const DexFile>> dex_files;
541 std::string error_msg;
542 ObjPtr<mirror::ClassLoader> class_loader;
543
544 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"), data_multi_location_path, &error_msg))
545 << error_msg;
546 ASSERT_TRUE(LoadDexFiles(data_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
547 << error_msg;
548 ASSERT_GE(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000549 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
550 dex_files,
551 hiddenapi::Domain::kApplication,
552 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000553
554 dex_files.clear();
555 ASSERT_EQ(0, remove(data_multi_location_path.c_str()));
556}
557
558TEST_F(HiddenApiTest, DexDomain_SystemDir_MultiDex) {
559 // Load multidex file from a system, non-framework directory and check that it is not flagged
560 // as framework.
561 std::string system_multi_location_path = GetAndroidRoot() + "/multifoo.jar";
562 ASSERT_FALSE(LocationIsOnSystemFramework(system_multi_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("MultiDex"), system_multi_location_path, &error_msg))
570 << error_msg;
571 ASSERT_TRUE(LoadDexFiles(system_multi_location_path, soa, &dex_files, &class_loader, &error_msg))
572 << error_msg;
573 ASSERT_GT(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000574 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
575 dex_files,
576 hiddenapi::Domain::kApplication,
577 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000578
579 dex_files.clear();
580 ASSERT_EQ(0, remove(system_multi_location_path.c_str()));
581}
582
583TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir_MultiDex) {
584 // Load multidex file from a system/framework directory and check that it is flagged as a
585 // framework dex.
586 std::string system_framework_multi_location_path = GetAndroidRoot() + "/framework/multifoo.jar";
587 ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_multi_location_path.c_str()));
588
589 ScopedObjectAccess soa(Thread::Current());
590 std::vector<std::unique_ptr<const DexFile>> dex_files;
591 std::string error_msg;
592 ObjPtr<mirror::ClassLoader> class_loader;
593
594 ASSERT_TRUE(Copy(GetTestDexFileName("MultiDex"),
595 system_framework_multi_location_path,
596 &error_msg)) << error_msg;
597 ASSERT_TRUE(LoadDexFiles(system_framework_multi_location_path,
598 soa,
599 &dex_files,
600 &class_loader,
601 &error_msg)) << error_msg;
602 ASSERT_GT(dex_files.size(), 1u);
David Brazdilbfaba282019-03-15 11:35:51 +0000603 ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
604 dex_files,
605 hiddenapi::Domain::kPlatform,
606 &error_msg)) << error_msg;
David Brazdila5c3a802019-03-08 14:59:41 +0000607
608 dex_files.clear();
609 ASSERT_EQ(0, remove(system_framework_multi_location_path.c_str()));
610}
611
Mathew Inwood7d74ef52018-03-16 14:18:33 +0000612} // namespace art