1 /*
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 
19 #include <fstream>
20 #include <sstream>
21 
22 #include "base/file_utils.h"
23 #include "base/sdk_version.h"
24 #include "base/stl_util.h"
25 #include "common_runtime_test.h"
26 #include "jni/jni_internal.h"
27 #include "proxy_test.h"
28 #include "well_known_classes.h"
29 
30 namespace art {
31 
32 using hiddenapi::detail::MemberSignature;
33 using hiddenapi::detail::ShouldDenyAccessToMemberImpl;
34 
35 class HiddenApiTest : public CommonRuntimeTest {
36  protected:
SetUp()37   void SetUp() override {
38     // Do the normal setup.
39     CommonRuntimeTest::SetUp();
40     self_ = Thread::Current();
41     self_->TransitionFromSuspendedToRunnable();
42     jclass_loader_ = LoadDex("HiddenApiSignatures");
43     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 
getArtMethod(const char * class_name,const char * name,const char * signature)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 
getArtField(const char * class_name,const char * name,const char * signature)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 
ShouldDenyAccess(hiddenapi::ApiList list)78   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 
87  protected:
88   Thread* self_;
89   jobject jclass_loader_;
90   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 
TEST_F(HiddenApiTest,CheckGetActionFromRuntimeFlags)106 TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
107   ScopedObjectAccess soa(self_);
108 
109   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
110   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Whitelist()), false);
111   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Greylist()), false);
112   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
113   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
114   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), false);
115 
116   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
117   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);
121   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxP()), false);
122   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), false);
123   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
124 
125   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
126   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);
130   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);
140   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::GreylistMaxO()), true);
141   ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blacklist()), true);
142 }
143 
TEST_F(HiddenApiTest,CheckMembersRead)144 TEST_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 
TEST_F(HiddenApiTest,CheckEverythingMatchesL)161 TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
162   ScopedObjectAccess soa(self_);
163   std::string prefix("L");
164   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));
178 }
179 
TEST_F(HiddenApiTest,CheckPackageMatch)180 TEST_F(HiddenApiTest, CheckPackageMatch) {
181   ScopedObjectAccess soa(self_);
182   std::string prefix("Lmypackage/packagea/");
183   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));
197 }
198 
TEST_F(HiddenApiTest,CheckClassMatch)199 TEST_F(HiddenApiTest, CheckClassMatch) {
200   ScopedObjectAccess soa(self_);
201   std::string prefix("Lmypackage/packagea/Class1");
202   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));
213 }
214 
TEST_F(HiddenApiTest,CheckClassExactMatch)215 TEST_F(HiddenApiTest, CheckClassExactMatch) {
216   ScopedObjectAccess soa(self_);
217   std::string prefix("Lmypackage/packagea/Class1;");
218   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));
228 }
229 
TEST_F(HiddenApiTest,CheckMethodMatch)230 TEST_F(HiddenApiTest, CheckMethodMatch) {
231   ScopedObjectAccess soa(self_);
232   std::string prefix("Lmypackage/packagea/Class1;->method1");
233   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));
241 }
242 
TEST_F(HiddenApiTest,CheckMethodExactMatch)243 TEST_F(HiddenApiTest, CheckMethodExactMatch) {
244   ScopedObjectAccess soa(self_);
245   std::string prefix("Lmypackage/packagea/Class1;->method1(");
246   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));
252 }
253 
TEST_F(HiddenApiTest,CheckMethodSignatureMatch)254 TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
255   ScopedObjectAccess soa(self_);
256   std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
257   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));
262 }
263 
TEST_F(HiddenApiTest,CheckMethodSignatureAndReturnMatch)264 TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
265   ScopedObjectAccess soa(self_);
266   std::string prefix("Lmypackage/packagea/Class1;->method1()V");
267   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));
272 }
273 
TEST_F(HiddenApiTest,CheckFieldMatch)274 TEST_F(HiddenApiTest, CheckFieldMatch) {
275   ScopedObjectAccess soa(self_);
276   std::string prefix("Lmypackage/packagea/Class1;->field1");
277   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));
282 }
283 
TEST_F(HiddenApiTest,CheckFieldExactMatch)284 TEST_F(HiddenApiTest, CheckFieldExactMatch) {
285   ScopedObjectAccess soa(self_);
286   std::string prefix("Lmypackage/packagea/Class1;->field1:");
287   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
288   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
289   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
290 }
291 
TEST_F(HiddenApiTest,CheckFieldTypeMatch)292 TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
293   ScopedObjectAccess soa(self_);
294   std::string prefix("Lmypackage/packagea/Class1;->field1:I");
295   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
296   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
297   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
298 }
299 
TEST_F(HiddenApiTest,CheckConstructorMatch)300 TEST_F(HiddenApiTest, CheckConstructorMatch) {
301   ScopedObjectAccess soa(self_);
302   std::string prefix("Lmypackage/packagea/Class1;-><init>");
303   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
304   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
305 }
306 
TEST_F(HiddenApiTest,CheckConstructorExactMatch)307 TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
308   ScopedObjectAccess soa(self_);
309   std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
310   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
311   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
312 }
313 
TEST_F(HiddenApiTest,CheckMethodSignatureTrailingCharsNoMatch)314 TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
315   ScopedObjectAccess soa(self_);
316   std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
317   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
318 }
319 
TEST_F(HiddenApiTest,CheckConstructorTrailingCharsNoMatch)320 TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
321   ScopedObjectAccess soa(self_);
322   std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
323   ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
324 }
325 
TEST_F(HiddenApiTest,CheckFieldTrailingCharsNoMatch)326 TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
327   ScopedObjectAccess soa(self_);
328   std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
329   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
330 }
331 
TEST_F(HiddenApiTest,CheckMemberSignatureForProxyClass)332 TEST_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.
344   std::vector<Handle<mirror::Class>> interfaces;
345   interfaces.push_back(h_iface);
346   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;
375   MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
376   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 
Copy(const std::string & src,const std::string & dst,std::string * error_msg)384 static 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 
LoadDexFiles(const std::string & path,ScopedObjectAccess & soa,std::vector<std::unique_ptr<const DexFile>> * dex_files,ObjPtr<mirror::ClassLoader> * class_loader,std::string * error_msg)400 static 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 
CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,const std::vector<std::unique_ptr<const DexFile>> & dex_files,hiddenapi::Domain expected_domain,std::string * error_msg)433 static bool CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,
434                                      const std::vector<std::unique_ptr<const DexFile>>& dex_files,
435                                      hiddenapi::Domain expected_domain,
436                                      /* out */ std::string* error_msg)
437     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) {
441       std::stringstream ss;
442       ss << dex_file->GetLocation() << ": access context domain does not match "
443           << "(expected=" << static_cast<uint32_t>(expected_domain)
444           << ", actual=" << static_cast<uint32_t>(context.GetDomain()) << ")";
445       *error_msg = ss.str();
446       return false;
447     }
448     if (dex_file->GetHiddenapiDomain() != expected_domain) {
449       std::stringstream ss;
450       ss << dex_file->GetLocation() << ": dex file domain does not match "
451           << "(expected=" << static_cast<uint32_t>(expected_domain)
452           << ", actual=" << static_cast<uint32_t>(dex_file->GetHiddenapiDomain()) << ")";
453       *error_msg = ss.str();
454       return false;
455     }
456   }
457 
458   return true;
459 }
460 
TEST_F(HiddenApiTest,DexDomain_DataDir)461 TEST_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);
475   ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
476                                        dex_files,
477                                        hiddenapi::Domain::kApplication,
478                                        &error_msg)) << error_msg;
479 
480   dex_files.clear();
481   ASSERT_EQ(0, remove(data_location_path.c_str()));
482 }
483 
TEST_F(HiddenApiTest,DexDomain_SystemDir)484 TEST_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);
498   ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
499                                        dex_files,
500                                        hiddenapi::Domain::kApplication,
501                                        &error_msg)) << error_msg;
502 
503   dex_files.clear();
504   ASSERT_EQ(0, remove(system_location_path.c_str()));
505 }
506 
TEST_F(HiddenApiTest,DexDomain_SystemFrameworkDir)507 TEST_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);
525   ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
526                                        dex_files,
527                                        hiddenapi::Domain::kPlatform,
528                                        &error_msg)) << error_msg;
529 
530   dex_files.clear();
531   ASSERT_EQ(0, remove(system_framework_location_path.c_str()));
532 }
533 
TEST_F(HiddenApiTest,DexDomain_DataDir_MultiDex)534 TEST_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);
549   ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
550                                        dex_files,
551                                        hiddenapi::Domain::kApplication,
552                                        &error_msg)) << error_msg;
553 
554   dex_files.clear();
555   ASSERT_EQ(0, remove(data_multi_location_path.c_str()));
556 }
557 
TEST_F(HiddenApiTest,DexDomain_SystemDir_MultiDex)558 TEST_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);
574   ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
575                                        dex_files,
576                                        hiddenapi::Domain::kApplication,
577                                        &error_msg)) << error_msg;
578 
579   dex_files.clear();
580   ASSERT_EQ(0, remove(system_multi_location_path.c_str()));
581 }
582 
TEST_F(HiddenApiTest,DexDomain_SystemFrameworkDir_MultiDex)583 TEST_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);
603   ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader,
604                                        dex_files,
605                                        hiddenapi::Domain::kPlatform,
606                                        &error_msg)) << error_msg;
607 
608   dex_files.clear();
609   ASSERT_EQ(0, remove(system_framework_multi_location_path.c_str()));
610 }
611 
612 }  // namespace art
613