Home | History | Annotate | Download | only in component_loader
      1 /*
      2  * Copyright (C) 2016 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 #include "component_loader/HalDriverLoader.h"
     17 
     18 #include <cutils/properties.h>
     19 #include <dirent.h>
     20 #include <google/protobuf/text_format.h>
     21 #include <iostream>
     22 
     23 #include "utils/InterfaceSpecUtil.h"
     24 #include "utils/StringUtil.h"
     25 
     26 static constexpr const char* kSpecFileExt = ".vts";
     27 static constexpr const char* kDefaultHwbinderServiceName = "default";
     28 
     29 namespace android {
     30 namespace vts {
     31 
     32 HalDriverLoader::HalDriverLoader(const string dir_path, int epoch_count,
     33                                  const string& callback_socket_name)
     34     : dir_path_(dir_path),
     35       epoch_count_(epoch_count),
     36       callback_socket_name_(callback_socket_name) {}
     37 
     38 bool HalDriverLoader::FindComponentSpecification(
     39     const int component_class, const string& package_name, const float version,
     40     const string& component_name, const int component_type,
     41     const string& submodule_name, ComponentSpecificationMessage* spec_msg) {
     42   DIR* dir;
     43   struct dirent* ent;
     44 
     45   // Derive the package-specific dir which contains .vts files
     46   string driver_lib_dir = dir_path_;
     47   if (!endsWith(driver_lib_dir, "/")) {
     48     driver_lib_dir += "/";
     49   }
     50   string package_path = package_name;
     51   ReplaceSubString(package_path, ".", "/");
     52   driver_lib_dir += package_path + "/";
     53   driver_lib_dir += GetVersionString(version);
     54 
     55   if (!(dir = opendir(driver_lib_dir.c_str()))) {
     56     cerr << __func__ << ": Can't open dir " << driver_lib_dir << endl;
     57     return false;
     58   }
     59 
     60   while ((ent = readdir(dir))) {
     61     if (ent->d_type == DT_REG &&
     62         string(ent->d_name).find(kSpecFileExt) != std::string::npos) {
     63       cout << __func__ << ": Checking a file " << ent->d_name << endl;
     64       const string file_path = driver_lib_dir + "/" + string(ent->d_name);
     65       if (ParseInterfaceSpec(file_path.c_str(), spec_msg)) {
     66         if (spec_msg->component_class() != component_class) {
     67           continue;
     68         }
     69         if (spec_msg->component_class() != HAL_HIDL) {
     70           if (spec_msg->component_type() != component_type ||
     71               spec_msg->component_type_version() != version) {
     72             continue;
     73           }
     74           if (!submodule_name.empty()) {
     75             if (spec_msg->component_class() != HAL_CONVENTIONAL_SUBMODULE ||
     76                 spec_msg->original_data_structure_name() != submodule_name) {
     77               continue;
     78             }
     79           }
     80           closedir(dir);
     81           return true;
     82         } else {
     83           if (spec_msg->package() != package_name ||
     84               spec_msg->component_type_version() != version) {
     85             continue;
     86           }
     87           if (!component_name.empty()) {
     88             if (spec_msg->component_name() != component_name) {
     89               continue;
     90             }
     91           }
     92           closedir(dir);
     93           return true;
     94         }
     95       }
     96     }
     97   }
     98   closedir(dir);
     99   return false;
    100 }
    101 
    102 DriverBase* HalDriverLoader::GetDriver(
    103     const string& driver_lib_path,
    104     const ComponentSpecificationMessage& spec_msg,
    105     const string& hw_binder_service_name, const uint64_t interface_pt,
    106     bool with_interface_pointer, const string& dll_file_name,
    107     const string& target_func_name) {
    108   DriverBase* driver = nullptr;
    109   if (spec_msg.component_class() == HAL_HIDL) {
    110     driver = GetHidlHalDriver(driver_lib_path, spec_msg, hw_binder_service_name,
    111                               interface_pt, with_interface_pointer);
    112   } else {
    113     driver = GetConventionalHalDriver(driver_lib_path, spec_msg, dll_file_name,
    114                                       target_func_name);
    115   }
    116   cout << __func__ << ":" << __LINE__ << " loaded target comp" << endl;
    117 
    118   return driver;
    119 }
    120 
    121 DriverBase* HalDriverLoader::GetConventionalHalDriver(
    122     const string& driver_lib_path,
    123     const ComponentSpecificationMessage& spec_msg, const string& dll_file_name,
    124     const string& /*target_func_name*/) {
    125   DriverBase* driver = LoadDriver(driver_lib_path, spec_msg);
    126   if (!driver) {
    127     cerr << __func__ << ": couldn't get a driver base class" << endl;
    128     return nullptr;
    129   }
    130   if (!driver->LoadTargetComponent(dll_file_name.c_str())) {
    131     cerr << __FUNCTION__ << ": couldn't load target component file, "
    132          << dll_file_name << endl;
    133     return nullptr;
    134   }
    135   return driver;
    136   /*
    137    * TODO: now always return the fuzzer. this change is due to the difficulty
    138    * in checking nested apis although that's possible. need to check whether
    139    * Fuzz() found the function, while still distinguishing the difference
    140    * between that and defined but non-set api.
    141   if (!strcmp(target_func_name, "#Open")) return driver;
    142 
    143   for (const vts::FunctionSpecificationMessage& func_msg : spec_msg.api())
    144   {
    145     cout << "checking " << func_msg.name() << endl;
    146     if (!strcmp(target_func_name, func_msg.name().c_str())) {
    147       return driver;
    148     }
    149   }
    150   return NULL;
    151   */
    152 }
    153 
    154 DriverBase* HalDriverLoader::GetDriverForSubModule(
    155     const string& spec_lib_file_path,
    156     const ComponentSpecificationMessage& spec_msg, void* object_pointer) {
    157   cout << __func__ << ":" << __LINE__ << " "
    158        << "entry object_pointer " << ((uint64_t)object_pointer) << endl;
    159   DriverBase* driver = LoadDriver(spec_lib_file_path, spec_msg);
    160   if (!driver) {
    161     cerr << __FUNCTION__ << ": couldn't get a driver base class" << endl;
    162     return nullptr;
    163   }
    164 
    165   cout << __func__ << ":" << __LINE__ << " "
    166        << "got fuzzer" << endl;
    167   if (spec_msg.component_class() == HAL_HIDL) {
    168     cerr << __func__ << " HIDL not supported" << endl;
    169     return nullptr;
    170   } else {
    171     if (!driver->SetTargetObject(object_pointer)) {
    172       cerr << __FUNCTION__ << ": couldn't set target object" << endl;
    173       return nullptr;
    174     }
    175   }
    176   cout << __func__ << ":" << __LINE__ << " "
    177        << "loaded target comp" << endl;
    178   return driver;
    179 }
    180 
    181 DriverBase* HalDriverLoader::GetFuzzerBaseAndAddAllFunctionsToQueue(
    182     const char* driver_lib_path,
    183     const ComponentSpecificationMessage& iface_spec_msg,
    184     const char* dll_file_name, const char* hw_service_name) {
    185   DriverBase* driver = GetDriver(driver_lib_path, iface_spec_msg,
    186                                  hw_service_name, 0, false, dll_file_name, "");
    187   if (!driver) {
    188     cerr << __FUNCTION__ << ": couldn't get a driver base class" << endl;
    189     return NULL;
    190   }
    191 
    192   for (const FunctionSpecificationMessage& func_msg :
    193        iface_spec_msg.interface().api()) {
    194     cout << "Add a job " << func_msg.name() << endl;
    195     FunctionSpecificationMessage* func_msg_copy = func_msg.New();
    196     func_msg_copy->CopyFrom(func_msg);
    197     job_queue_.push(make_pair(func_msg_copy, driver));
    198   }
    199   return driver;
    200 }
    201 
    202 DriverBase* HalDriverLoader::GetHidlHalDriver(
    203     const string& driver_lib_path,
    204     const ComponentSpecificationMessage& spec_msg,
    205     const string& hal_service_name, const uint64_t interface_pt,
    206     bool with_interface_pt) {
    207   string package_name = spec_msg.package();
    208 
    209   DriverBase* driver = nullptr;
    210   if (with_interface_pt) {
    211     driver =
    212         LoadDriverWithInterfacePointer(driver_lib_path, spec_msg, interface_pt);
    213   } else {
    214     driver = LoadDriver(driver_lib_path, spec_msg);
    215   }
    216   if (!driver) {
    217     cerr << __func__ << ": couldn't get a driver base class" << endl;
    218     return nullptr;
    219   }
    220   cout << __func__ << ":" << __LINE__ << " "
    221        << "got driver" << endl;
    222 
    223   if (!with_interface_pt) {
    224     string service_name;
    225     if (!hal_service_name.empty()) {
    226       service_name = hal_service_name;
    227     } else {
    228       service_name = kDefaultHwbinderServiceName;
    229     }
    230 
    231     char get_sub_property[PROPERTY_VALUE_MAX];
    232     bool get_stub = false; /* default is binderized */
    233     if (property_get("vts.hidl.get_stub", get_sub_property, "") > 0) {
    234       if (!strcmp(get_sub_property, "true") ||
    235           !strcmp(get_sub_property, "True") || !strcmp(get_sub_property, "1")) {
    236         get_stub = true;
    237       }
    238     }
    239     if (!driver->GetService(get_stub, service_name.c_str())) {
    240       cerr << __FUNCTION__ << ": couldn't get service" << endl;
    241       return nullptr;
    242     }
    243   } else {
    244     cout << __func__ << ":" << __LINE__
    245          << " created DriverBase with interface pointer:" << interface_pt
    246          << endl;
    247   }
    248   cout << __func__ << ":" << __LINE__ << " loaded target comp" << endl;
    249   return driver;
    250 }
    251 
    252 DriverBase* HalDriverLoader::LoadDriver(
    253     const string& driver_lib_path,
    254     const ComponentSpecificationMessage& spec_msg) {
    255   if (!dll_loader_.Load(driver_lib_path.c_str(), false)) {
    256     cerr << __func__ << ": failed to load  " << driver_lib_path << endl;
    257     return nullptr;
    258   }
    259   cout << "DLL loaded " << driver_lib_path << endl;
    260   string function_name_prefix = GetFunctionNamePrefix(spec_msg);
    261   loader_function func =
    262       dll_loader_.GetLoaderFunction(function_name_prefix.c_str());
    263   if (!func) {
    264     cerr << __func__ << ": function not found." << endl;
    265     return nullptr;
    266   }
    267   cout << __func__ << ": function found; trying to call." << endl;
    268   DriverBase* driver = func();
    269   return driver;
    270 }
    271 
    272 DriverBase* HalDriverLoader::LoadDriverWithInterfacePointer(
    273     const string& driver_lib_path,
    274     const ComponentSpecificationMessage& spec_msg,
    275     const uint64_t interface_pt) {
    276   // Assumption: no shared library lookup is needed because that is handled
    277   // the by the driver's linking dependency.
    278   // Example: name (android::hardware::gnss::V1_0::IAGnssRil) converted to
    279   // function name (vts_func_4_android_hardware_tests_bar_V1_0_IBar_with_arg)
    280   if (!dll_loader_.Load(driver_lib_path.c_str(), false)) {
    281     cerr << __func__ << ": failed to load  " << driver_lib_path << endl;
    282     return nullptr;
    283   }
    284   cout << "DLL loaded " << driver_lib_path << endl;
    285   string function_name_prefix = GetFunctionNamePrefix(spec_msg);
    286   function_name_prefix += "with_arg";
    287   loader_function_with_arg func =
    288       dll_loader_.GetLoaderFunctionWithArg(function_name_prefix.c_str());
    289   if (!func) {
    290     cerr << __func__ << ": function not found." << endl;
    291     return nullptr;
    292   }
    293   return func(interface_pt);
    294 }
    295 
    296 bool HalDriverLoader::Process(const char* dll_file_name,
    297                               const char* spec_lib_file_path, int target_class,
    298                               int target_type, float target_version,
    299                               const char* target_package,
    300                               const char* target_component_name,
    301                               const char* hal_service_name) {
    302   ComponentSpecificationMessage interface_specification_message;
    303   if (!FindComponentSpecification(target_class, target_package, target_version,
    304                                   target_component_name, target_type, "",
    305                                   &interface_specification_message)) {
    306     cerr << __func__ << ": no interface specification file found for class "
    307          << target_class << " type " << target_type << " version "
    308          << target_version << endl;
    309     return false;
    310   }
    311 
    312   if (!GetFuzzerBaseAndAddAllFunctionsToQueue(
    313           spec_lib_file_path, interface_specification_message, dll_file_name,
    314           hal_service_name)) {
    315     return false;
    316   }
    317 
    318   for (int i = 0; i < epoch_count_; i++) {
    319     // by default, breath-first-searching is used.
    320     if (job_queue_.empty()) {
    321       cerr << "no more job to process; stopping after epoch " << i << endl;
    322       break;
    323     }
    324 
    325     pair<vts::FunctionSpecificationMessage*, DriverBase*> curr_job =
    326         job_queue_.front();
    327     job_queue_.pop();
    328 
    329     vts::FunctionSpecificationMessage* func_msg = curr_job.first;
    330     DriverBase* func_fuzzer = curr_job.second;
    331 
    332     void* result;
    333     FunctionSpecificationMessage result_msg;
    334     cout << "Iteration " << (i + 1) << " Function " << func_msg->name() << endl;
    335     // For Hidl HAL, use CallFunction method.
    336     if (interface_specification_message.component_class() == HAL_HIDL) {
    337       func_fuzzer->CallFunction(*func_msg, callback_socket_name_, &result_msg);
    338     } else {
    339       func_fuzzer->Fuzz(func_msg, &result, callback_socket_name_);
    340     }
    341     if (func_msg->return_type().type() == TYPE_PREDEFINED) {
    342       if (result != NULL) {
    343         // loads that interface spec and enqueues all functions.
    344         cout << __FUNCTION__
    345              << " return type: " << func_msg->return_type().predefined_type()
    346              << endl;
    347         // TODO: handle the case when size > 1
    348         string submodule_name = func_msg->return_type().predefined_type();
    349         while (!submodule_name.empty() &&
    350                (std::isspace(submodule_name.back()) ||
    351                 submodule_name.back() == '*')) {
    352           submodule_name.pop_back();
    353         }
    354         ComponentSpecificationMessage iface_spec_msg;
    355         if (FindComponentSpecification(target_class, "", target_version, "",
    356                                        target_type, submodule_name,
    357                                        &iface_spec_msg)) {
    358           cout << __FUNCTION__ << " submodule found - " << submodule_name
    359                << endl;
    360           if (!GetFuzzerBaseAndAddAllFunctionsToQueue(
    361                   spec_lib_file_path, iface_spec_msg, dll_file_name,
    362                   hal_service_name)) {
    363             return false;
    364           }
    365         } else {
    366           cout << __FUNCTION__ << " submodule not found - " << submodule_name
    367                << endl;
    368         }
    369       } else {
    370         cout << __FUNCTION__ << " return value = NULL" << endl;
    371       }
    372     }
    373   }
    374 
    375   return true;
    376 }
    377 
    378 }  // namespace vts
    379 }  // namespace android
    380