• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
HalDriverLoader(const string dir_path,int epoch_count,const string & callback_socket_name)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 
FindComponentSpecification(const int component_class,const string & package_name,const float version,const string & component_name,const int component_type,const string & submodule_name,ComponentSpecificationMessage * spec_msg)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 
GetDriver(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg,const string & hw_binder_service_name,const uint64_t interface_pt,bool with_interface_pointer,const string & dll_file_name,const string & target_func_name)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 
GetConventionalHalDriver(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg,const string & dll_file_name,const string &)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 
GetDriverForSubModule(const string & spec_lib_file_path,const ComponentSpecificationMessage & spec_msg,void * object_pointer)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 
GetFuzzerBaseAndAddAllFunctionsToQueue(const char * driver_lib_path,const ComponentSpecificationMessage & iface_spec_msg,const char * dll_file_name,const char * hw_service_name)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 
GetHidlHalDriver(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg,const string & hal_service_name,const uint64_t interface_pt,bool with_interface_pt)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 
LoadDriver(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg)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 
LoadDriverWithInterfacePointer(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg,const uint64_t interface_pt)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 
Process(const char * dll_file_name,const char * spec_lib_file_path,int target_class,int target_type,float target_version,const char * target_package,const char * target_component_name,const char * hal_service_name)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