Home | History | Annotate | Download | only in runtime
      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 "common_runtime_test.h"
     20 #include "jni_internal.h"
     21 #include "proxy_test.h"
     22 
     23 namespace art {
     24 
     25 using hiddenapi::detail::MemberSignature;
     26 using hiddenapi::GetActionFromAccessFlags;
     27 
     28 class HiddenApiTest : public CommonRuntimeTest {
     29  protected:
     30   void SetUp() OVERRIDE {
     31     // Do the normal setup.
     32     CommonRuntimeTest::SetUp();
     33     self_ = Thread::Current();
     34     self_->TransitionFromSuspendedToRunnable();
     35     jclass_loader_ = LoadDex("HiddenApiSignatures");
     36     bool started = runtime_->Start();
     37     CHECK(started);
     38 
     39     class1_field1_ = getArtField("mypackage/packagea/Class1", "field1", "I");
     40     class1_field12_ = getArtField("mypackage/packagea/Class1", "field12", "I");
     41     class1_init_ = getArtMethod("mypackage/packagea/Class1", "<init>", "()V");
     42     class1_method1_ = getArtMethod("mypackage/packagea/Class1", "method1", "()V");
     43     class1_method1_i_ = getArtMethod("mypackage/packagea/Class1", "method1", "(I)V");
     44     class1_method12_ = getArtMethod("mypackage/packagea/Class1", "method12", "()V");
     45     class12_field1_ = getArtField("mypackage/packagea/Class12", "field1", "I");
     46     class12_method1_ = getArtMethod("mypackage/packagea/Class12", "method1", "()V");
     47     class2_field1_ = getArtField("mypackage/packagea/Class2", "field1", "I");
     48     class2_method1_ = getArtMethod("mypackage/packagea/Class2", "method1", "()V");
     49     class2_method1_i_ = getArtMethod("mypackage/packagea/Class2", "method1", "(I)V");
     50     class3_field1_ = getArtField("mypackage/packageb/Class3", "field1", "I");
     51     class3_method1_ = getArtMethod("mypackage/packageb/Class3", "method1", "()V");
     52     class3_method1_i_ = getArtMethod("mypackage/packageb/Class3", "method1", "(I)V");
     53   }
     54 
     55   ArtMethod* getArtMethod(const char* class_name, const char* name, const char* signature) {
     56     JNIEnv* env = Thread::Current()->GetJniEnv();
     57     jclass klass = env->FindClass(class_name);
     58     jmethodID method_id = env->GetMethodID(klass, name, signature);
     59     ArtMethod* art_method = jni::DecodeArtMethod(method_id);
     60     return art_method;
     61   }
     62 
     63   ArtField* getArtField(const char* class_name, const char* name, const char* signature) {
     64     JNIEnv* env = Thread::Current()->GetJniEnv();
     65     jclass klass = env->FindClass(class_name);
     66     jfieldID field_id = env->GetFieldID(klass, name, signature);
     67     ArtField* art_field = jni::DecodeArtField(field_id);
     68     return art_field;
     69   }
     70 
     71  protected:
     72   Thread* self_;
     73   jobject jclass_loader_;
     74   ArtField* class1_field1_;
     75   ArtField* class1_field12_;
     76   ArtMethod* class1_init_;
     77   ArtMethod* class1_method1_;
     78   ArtMethod* class1_method1_i_;
     79   ArtMethod* class1_method12_;
     80   ArtField* class12_field1_;
     81   ArtMethod* class12_method1_;
     82   ArtField* class2_field1_;
     83   ArtMethod* class2_method1_;
     84   ArtMethod* class2_method1_i_;
     85   ArtField* class3_field1_;
     86   ArtMethod* class3_method1_;
     87   ArtMethod* class3_method1_i_;
     88 };
     89 
     90 TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
     91   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kNoChecks);
     92   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kWhitelist), hiddenapi::kAllow);
     93   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kLightGreylist), hiddenapi::kAllow);
     94   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kDarkGreylist), hiddenapi::kAllow);
     95   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kBlacklist), hiddenapi::kAllow);
     96 
     97   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
     98   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kWhitelist),
     99             hiddenapi::kAllow);
    100   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kLightGreylist),
    101             hiddenapi::kAllowButWarn);
    102   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kDarkGreylist),
    103             hiddenapi::kAllowButWarn);
    104   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kBlacklist),
    105             hiddenapi::kAllowButWarn);
    106 
    107   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kDarkGreyAndBlackList);
    108   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kWhitelist),
    109             hiddenapi::kAllow);
    110   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kLightGreylist),
    111             hiddenapi::kAllowButWarn);
    112   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kDarkGreylist),
    113             hiddenapi::kDeny);
    114   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kBlacklist),
    115             hiddenapi::kDeny);
    116 
    117   runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kBlacklistOnly);
    118   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kWhitelist),
    119             hiddenapi::kAllow);
    120   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kLightGreylist),
    121             hiddenapi::kAllowButWarn);
    122   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kDarkGreylist),
    123             hiddenapi::kAllowButWarnAndToast);
    124   ASSERT_EQ(GetActionFromAccessFlags(HiddenApiAccessFlags::kBlacklist),
    125             hiddenapi::kDeny);
    126 }
    127 
    128 TEST_F(HiddenApiTest, CheckMembersRead) {
    129   ASSERT_NE(nullptr, class1_field1_);
    130   ASSERT_NE(nullptr, class1_field12_);
    131   ASSERT_NE(nullptr, class1_init_);
    132   ASSERT_NE(nullptr, class1_method1_);
    133   ASSERT_NE(nullptr, class1_method1_i_);
    134   ASSERT_NE(nullptr, class1_method12_);
    135   ASSERT_NE(nullptr, class12_field1_);
    136   ASSERT_NE(nullptr, class12_method1_);
    137   ASSERT_NE(nullptr, class2_field1_);
    138   ASSERT_NE(nullptr, class2_method1_);
    139   ASSERT_NE(nullptr, class2_method1_i_);
    140   ASSERT_NE(nullptr, class3_field1_);
    141   ASSERT_NE(nullptr, class3_method1_);
    142   ASSERT_NE(nullptr, class3_method1_i_);
    143 }
    144 
    145 TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
    146   ScopedObjectAccess soa(self_);
    147   std::string prefix("L");
    148   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    149   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    150   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    151   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    152   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    153   ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
    154   ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
    155   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    156   ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
    157   ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
    158   ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
    159   ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
    160   ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
    161   ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
    162 }
    163 
    164 TEST_F(HiddenApiTest, CheckPackageMatch) {
    165   ScopedObjectAccess soa(self_);
    166   std::string prefix("Lmypackage/packagea/");
    167   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    168   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    169   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    170   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    171   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    172   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    173   ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
    174   ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
    175   ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
    176   ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
    177   ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
    178   ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
    179   ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
    180   ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
    181 }
    182 
    183 TEST_F(HiddenApiTest, CheckClassMatch) {
    184   ScopedObjectAccess soa(self_);
    185   std::string prefix("Lmypackage/packagea/Class1");
    186   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    187   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    188   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    189   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    190   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    191   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    192   ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
    193   ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
    194   ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
    195   ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
    196   ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
    197 }
    198 
    199 TEST_F(HiddenApiTest, CheckClassExactMatch) {
    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_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
    208   ASSERT_FALSE(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));
    212 }
    213 
    214 TEST_F(HiddenApiTest, CheckMethodMatch) {
    215   ScopedObjectAccess soa(self_);
    216   std::string prefix("Lmypackage/packagea/Class1;->method1");
    217   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    218   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    219   ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    220   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    221   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    222   ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    223   ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
    224   ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
    225 }
    226 
    227 TEST_F(HiddenApiTest, CheckMethodExactMatch) {
    228   ScopedObjectAccess soa(self_);
    229   std::string prefix("Lmypackage/packagea/Class1;->method1(");
    230   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    231   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    232   ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    233   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    234   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    235   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    236 }
    237 
    238 TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
    239   ScopedObjectAccess soa(self_);
    240   std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
    241   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    242   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    243   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    244   ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    245   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    246 }
    247 
    248 TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
    249   ScopedObjectAccess soa(self_);
    250   std::string prefix("Lmypackage/packagea/Class1;->method1()V");
    251   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    252   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    253   ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    254   ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    255   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    256 }
    257 
    258 TEST_F(HiddenApiTest, CheckFieldMatch) {
    259   ScopedObjectAccess soa(self_);
    260   std::string prefix("Lmypackage/packagea/Class1;->field1");
    261   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    262   ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    263   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    264   ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
    265   ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
    266 }
    267 
    268 TEST_F(HiddenApiTest, CheckFieldExactMatch) {
    269   ScopedObjectAccess soa(self_);
    270   std::string prefix("Lmypackage/packagea/Class1;->field1:");
    271   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    272   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    273   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    274 }
    275 
    276 TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
    277   ScopedObjectAccess soa(self_);
    278   std::string prefix("Lmypackage/packagea/Class1;->field1:I");
    279   ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    280   ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
    281   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    282 }
    283 
    284 TEST_F(HiddenApiTest, CheckConstructorMatch) {
    285   ScopedObjectAccess soa(self_);
    286   std::string prefix("Lmypackage/packagea/Class1;-><init>");
    287   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    288   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    289 }
    290 
    291 TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
    292   ScopedObjectAccess soa(self_);
    293   std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
    294   ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    295   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    296 }
    297 
    298 TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
    299   ScopedObjectAccess soa(self_);
    300   std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
    301   ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
    302 }
    303 
    304 TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
    305   ScopedObjectAccess soa(self_);
    306   std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
    307   ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
    308 }
    309 
    310 TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
    311   ScopedObjectAccess soa(self_);
    312   std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
    313   ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
    314 }
    315 
    316 TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
    317   ScopedObjectAccess soa(self_);
    318   StackHandleScope<4> hs(soa.Self());
    319   Handle<mirror::ClassLoader> class_loader(
    320       hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
    321 
    322   // Find interface we will create a proxy for.
    323   Handle<mirror::Class> h_iface(hs.NewHandle(
    324       class_linker_->FindClass(soa.Self(), "Lmypackage/packagea/Interface;", class_loader)));
    325   ASSERT_TRUE(h_iface != nullptr);
    326 
    327   // Create the proxy class.
    328   std::vector<mirror::Class*> interfaces;
    329   interfaces.push_back(h_iface.Get());
    330   Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
    331       soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
    332   ASSERT_TRUE(proxyClass != nullptr);
    333   ASSERT_TRUE(proxyClass->IsProxyClass());
    334   ASSERT_TRUE(proxyClass->IsInitialized());
    335 
    336   // Find the "method" virtual method.
    337   ArtMethod* method = nullptr;
    338   for (auto& m : proxyClass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
    339     if (strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
    340       method = &m;
    341       break;
    342     }
    343   }
    344   ASSERT_TRUE(method != nullptr);
    345 
    346   // Find the "interfaces" static field. This is generated for all proxies.
    347   ArtField* field = nullptr;
    348   for (size_t i = 0; i < proxyClass->NumStaticFields(); ++i) {
    349     ArtField* f = proxyClass->GetStaticField(i);
    350     if (strcmp("interfaces", f->GetName()) == 0) {
    351       field = f;
    352       break;
    353     }
    354   }
    355   ASSERT_TRUE(field != nullptr);
    356 
    357   // Test the signature. We expect the signature from the interface class.
    358   std::ostringstream ss_method;
    359   MemberSignature(method).Dump(ss_method);
    360   ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());
    361 
    362   // Test the signature. We expect the signature of the proxy class.
    363   std::ostringstream ss_field;
    364   MemberSignature(field).Dump(ss_field);
    365   ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
    366 }
    367 
    368 }  // namespace art
    369