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