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 #define LOG_TAG "VtsHalDriverLoader"
17
18 #include "component_loader/HalDriverLoader.h"
19
20 #include <dirent.h>
21
22 #include <android-base/logging.h>
23 #include <cutils/properties.h>
24 #include <google/protobuf/text_format.h>
25
26 #include "utils/InterfaceSpecUtil.h"
27 #include "utils/StringUtil.h"
28
29 static constexpr const char* kSpecFileExt = ".vts";
30 static constexpr const char* kDefaultHwbinderServiceName = "default";
31
32 namespace android {
33 namespace vts {
34
HalDriverLoader(const string dir_path,int epoch_count,const string & callback_socket_name)35 HalDriverLoader::HalDriverLoader(const string dir_path, int epoch_count,
36 const string& callback_socket_name)
37 : dir_path_(dir_path),
38 epoch_count_(epoch_count),
39 callback_socket_name_(callback_socket_name) {}
40
FindComponentSpecification(const int component_class,const string & package_name,const int version_major,const int version_minor,const string & component_name,const int component_type,ComponentSpecificationMessage * spec_msg)41 bool HalDriverLoader::FindComponentSpecification(
42 const int component_class, const string& package_name,
43 const int version_major, const int version_minor,
44 const string& component_name, const int component_type,
45 ComponentSpecificationMessage* spec_msg) {
46 DIR* dir;
47 struct dirent* ent;
48
49 // Derive the package-specific dir which contains .vts files
50 string driver_lib_dir = dir_path_;
51 if (!endsWith(driver_lib_dir, "/")) {
52 driver_lib_dir += "/";
53 }
54 string package_path = package_name;
55 ReplaceSubString(package_path, ".", "/");
56 driver_lib_dir += package_path + "/";
57 driver_lib_dir += GetVersionString(version_major, version_minor);
58
59 if (!(dir = opendir(driver_lib_dir.c_str()))) {
60 LOG(ERROR) << "Can't open dir " << driver_lib_dir;
61 return false;
62 }
63
64 while ((ent = readdir(dir))) {
65 if (ent->d_type == DT_REG &&
66 string(ent->d_name).find(kSpecFileExt) != std::string::npos) {
67 LOG(DEBUG) << "Checking a file " << ent->d_name;
68 const string file_path = driver_lib_dir + "/" + string(ent->d_name);
69 if (ParseInterfaceSpec(file_path.c_str(), spec_msg)) {
70 if (spec_msg->component_class() != component_class) {
71 continue;
72 }
73 if (spec_msg->component_class() != HAL_HIDL) {
74 if (spec_msg->component_type() != component_type ||
75 spec_msg->component_type_version_major() != version_major ||
76 spec_msg->component_type_version_minor() != version_minor) {
77 continue;
78 }
79 closedir(dir);
80 return true;
81 } else {
82 if (spec_msg->package() != package_name ||
83 spec_msg->component_type_version_major() != version_major ||
84 spec_msg->component_type_version_minor() != version_minor) {
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)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 DriverBase* driver = nullptr;
108 if (spec_msg.component_class() == HAL_HIDL) {
109 driver = GetHidlHalDriver(driver_lib_path, spec_msg, hw_binder_service_name,
110 interface_pt, with_interface_pointer);
111 } else {
112 driver = GetLibDriver(driver_lib_path, spec_msg, dll_file_name);
113 }
114 LOG(DEBUG) << "Loaded target comp";
115
116 return driver;
117 }
118
GetLibDriver(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg,const string & dll_file_name)119 DriverBase* HalDriverLoader::GetLibDriver(
120 const string& driver_lib_path,
121 const ComponentSpecificationMessage& spec_msg,
122 const string& dll_file_name) {
123 DriverBase* driver = LoadDriver(driver_lib_path, spec_msg);
124 if (!driver) {
125 LOG(ERROR) << "Couldn't get a driver base class";
126 return nullptr;
127 }
128 if (!driver->LoadTargetComponent(dll_file_name.c_str())) {
129 LOG(ERROR) << "Couldn't load target component file, " << dll_file_name;
130 return nullptr;
131 }
132 return driver;
133 }
134
GetFuzzerBaseAndAddAllFunctionsToQueue(const char * driver_lib_path,const ComponentSpecificationMessage & iface_spec_msg,const char * dll_file_name,const char * hw_service_name)135 DriverBase* HalDriverLoader::GetFuzzerBaseAndAddAllFunctionsToQueue(
136 const char* driver_lib_path,
137 const ComponentSpecificationMessage& iface_spec_msg,
138 const char* dll_file_name, const char* hw_service_name) {
139 DriverBase* driver = GetDriver(driver_lib_path, iface_spec_msg,
140 hw_service_name, 0, false, dll_file_name);
141 if (!driver) {
142 LOG(ERROR) << "Couldn't get a driver base class";
143 return NULL;
144 }
145
146 for (const FunctionSpecificationMessage& func_msg :
147 iface_spec_msg.interface().api()) {
148 LOG(DEBUG) << "Add a job " << func_msg.name();
149 FunctionSpecificationMessage* func_msg_copy = func_msg.New();
150 func_msg_copy->CopyFrom(func_msg);
151 job_queue_.push(make_pair(func_msg_copy, driver));
152 }
153 return driver;
154 }
155
GetHidlHalDriver(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg,const string & hal_service_name,const uint64_t interface_pt,bool with_interface_pt)156 DriverBase* HalDriverLoader::GetHidlHalDriver(
157 const string& driver_lib_path,
158 const ComponentSpecificationMessage& spec_msg,
159 const string& hal_service_name, const uint64_t interface_pt,
160 bool with_interface_pt) {
161 string package_name = spec_msg.package();
162
163 DriverBase* driver = nullptr;
164 if (with_interface_pt) {
165 driver =
166 LoadDriverWithInterfacePointer(driver_lib_path, spec_msg, interface_pt);
167 } else {
168 driver = LoadDriver(driver_lib_path, spec_msg);
169 }
170 if (!driver) {
171 LOG(ERROR) << "Couldn't get a driver base class";
172 return nullptr;
173 }
174 LOG(DEBUG) << "Got Hidl Hal driver";
175
176 if (!with_interface_pt) {
177 string service_name;
178 if (!hal_service_name.empty()) {
179 service_name = hal_service_name;
180 } else {
181 service_name = kDefaultHwbinderServiceName;
182 }
183
184 char get_sub_property[PROPERTY_VALUE_MAX];
185 bool get_stub = false; /* default is binderized */
186 if (property_get("vts.hidl.get_stub", get_sub_property, "") > 0) {
187 if (!strcmp(get_sub_property, "true") ||
188 !strcmp(get_sub_property, "True") || !strcmp(get_sub_property, "1")) {
189 get_stub = true;
190 }
191 }
192 if (!driver->GetService(get_stub, service_name.c_str())) {
193 LOG(ERROR) << "Couldn't get hal service";
194 return nullptr;
195 }
196 } else {
197 LOG(INFO) << "Created DriverBase with interface pointer:" << interface_pt;
198 }
199 LOG(DEBUG) << "Loaded target comp";
200 return driver;
201 }
202
LoadDriver(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg)203 DriverBase* HalDriverLoader::LoadDriver(
204 const string& driver_lib_path,
205 const ComponentSpecificationMessage& spec_msg) {
206 if (!dll_loader_.Load(driver_lib_path.c_str())) {
207 LOG(ERROR) << "Failed to load " << driver_lib_path;
208 return nullptr;
209 }
210 LOG(DEBUG) << "DLL loaded " << driver_lib_path;
211 string function_name_prefix = GetFunctionNamePrefix(spec_msg);
212 loader_function func =
213 dll_loader_.GetLoaderFunction(function_name_prefix.c_str());
214 if (!func) {
215 LOG(ERROR) << "Function not found.";
216 return nullptr;
217 }
218 LOG(DEBUG) << "Function found; trying to call.";
219 DriverBase* driver = func();
220 return driver;
221 }
222
LoadDriverWithInterfacePointer(const string & driver_lib_path,const ComponentSpecificationMessage & spec_msg,const uint64_t interface_pt)223 DriverBase* HalDriverLoader::LoadDriverWithInterfacePointer(
224 const string& driver_lib_path,
225 const ComponentSpecificationMessage& spec_msg,
226 const uint64_t interface_pt) {
227 // Assumption: no shared library lookup is needed because that is handled
228 // the by the driver's linking dependency.
229 // Example: name (android::hardware::gnss::V1_0::IAGnssRil) converted to
230 // function name (vts_func_4_android_hardware_tests_bar_V1_0_IBar_with_arg)
231 if (!dll_loader_.Load(driver_lib_path.c_str())) {
232 LOG(ERROR) << "Failed to load " << driver_lib_path;
233 return nullptr;
234 }
235 LOG(DEBUG) << "DLL loaded " << driver_lib_path;
236 string function_name_prefix = GetFunctionNamePrefix(spec_msg);
237 function_name_prefix += "with_arg";
238 loader_function_with_arg func =
239 dll_loader_.GetLoaderFunctionWithArg(function_name_prefix.c_str());
240 if (!func) {
241 LOG(ERROR) << "Function not found.";
242 return nullptr;
243 }
244 return func(interface_pt);
245 }
246
Process(const char * dll_file_name,const char * spec_lib_file_path,int target_class,int target_type,int target_version_major,int target_version_minor,const char * target_package,const char * target_component_name,const char * hal_service_name)247 bool HalDriverLoader::Process(const char* dll_file_name,
248 const char* spec_lib_file_path, int target_class,
249 int target_type, int target_version_major,
250 int target_version_minor,
251 const char* target_package,
252 const char* target_component_name,
253 const char* hal_service_name) {
254 ComponentSpecificationMessage interface_specification_message;
255 if (!FindComponentSpecification(target_class, target_package,
256 target_version_major, target_version_minor,
257 target_component_name, target_type,
258 &interface_specification_message)) {
259 LOG(ERROR) << "No interface specification file found for class "
260 << target_class << " type " << target_type << " version "
261 << GetVersionString(target_version_major, target_version_minor);
262 return false;
263 }
264
265 if (!GetFuzzerBaseAndAddAllFunctionsToQueue(
266 spec_lib_file_path, interface_specification_message, dll_file_name,
267 hal_service_name)) {
268 return false;
269 }
270
271 for (int i = 0; i < epoch_count_; i++) {
272 // by default, breath-first-searching is used.
273 if (job_queue_.empty()) {
274 LOG(ERROR) << "No more job to process; stopping after epoch " << i;
275 break;
276 }
277
278 pair<vts::FunctionSpecificationMessage*, DriverBase*> curr_job =
279 job_queue_.front();
280 job_queue_.pop();
281
282 vts::FunctionSpecificationMessage* func_msg = curr_job.first;
283 DriverBase* func_fuzzer = curr_job.second;
284
285 void* result;
286 FunctionSpecificationMessage result_msg;
287 LOG(INFO) << "Iteration " << (i + 1) << " Function " << func_msg->name();
288 // For Hidl HAL, use CallFunction method.
289 if (interface_specification_message.component_class() == HAL_HIDL) {
290 func_fuzzer->CallFunction(*func_msg, callback_socket_name_, &result_msg);
291 } else {
292 func_fuzzer->Fuzz(func_msg, &result, callback_socket_name_);
293 }
294 }
295
296 return true;
297 }
298
299 } // namespace vts
300 } // namespace android
301