blob: 3751a034eed2914d280063bc64deaa36bfc0f174 [file] [log] [blame]
Keun Soo Yim08400372016-03-03 13:28:51 -08001/*
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
17#include "specification_parser/SpecificationBuilder.h"
18
19#include <dirent.h>
20
21#include <iostream>
Keun Soo Yim2ee90792016-04-27 14:53:54 -070022#include <queue>
Keun Soo Yim08400372016-03-03 13:28:51 -080023#include <string>
24
25#include "fuzz_tester/FuzzerBase.h"
26#include "fuzz_tester/FuzzerWrapper.h"
27#include "specification_parser/InterfaceSpecificationParser.h"
28
29#include "test/vts/sysfuzzer/common/proto/InterfaceSpecificationMessage.pb.h"
30
31namespace android {
32namespace vts {
33
Keun Soo Yim8103c912016-04-22 20:07:13 -070034SpecificationBuilder::SpecificationBuilder(
35 const string dir_path, int epoch_count)
36 : dir_path_(dir_path),
37 epoch_count_(epoch_count) {}
Keun Soo Yim08400372016-03-03 13:28:51 -080038
39
40vts::InterfaceSpecificationMessage*
41SpecificationBuilder::FindInterfaceSpecification(
42 const int target_class,
43 const int target_type,
Keun Soo Yim2ee90792016-04-27 14:53:54 -070044 const float target_version,
45 const string submodule_name) {
Keun Soo Yim08400372016-03-03 13:28:51 -080046 DIR* dir;
47 struct dirent* ent;
48
49 if (!(dir = opendir(dir_path_.c_str()))) {
50 cerr << __FUNCTION__ << ": Can't opendir " << dir_path_ << endl;
51 return NULL;
52 }
53
54 while ((ent = readdir(dir))) {
55 if (string(ent->d_name).find(SPEC_FILE_EXT) != std::string::npos) {
56 cout << __FUNCTION__ << ": Checking a file " << ent->d_name << endl;
57 const string file_path = string(dir_path_) + "/" + string(ent->d_name);
58 vts::InterfaceSpecificationMessage* message =
59 new vts::InterfaceSpecificationMessage();
60 if (InterfaceSpecificationParser::parse(file_path.c_str(), message)) {
Keun Soo Yim2ee90792016-04-27 14:53:54 -070061 if (message->component_type() == target_type
Keun Soo Yim08400372016-03-03 13:28:51 -080062 && message->component_type_version() == target_version) {
Keun Soo Yim2ee90792016-04-27 14:53:54 -070063 if (submodule_name.length() > 0) {
64 if (message->component_class() != HAL_SUBMODULE
65 || message->original_data_structure_name() != submodule_name) {
66 continue;
67 }
68 } else if (message->component_class() != target_class) continue;
Keun Soo Yim08400372016-03-03 13:28:51 -080069 closedir(dir);
70 return message;
71 }
72 }
73 delete message;
74 }
75 }
76 closedir(dir);
77 return NULL;
78}
79
80
Keun Soo Yim2ee90792016-04-27 14:53:54 -070081FuzzerBase* SpecificationBuilder::GetFuzzerBaseAndAddAllFunctionsToQueue(
82 const vts::InterfaceSpecificationMessage& iface_spec_msg,
83 const char* dll_file_name) {
84 FuzzerBase* fuzzer = wrapper_.GetFuzzer(iface_spec_msg);
85 if (!fuzzer) {
86 cerr << __FUNCTION__ << ": couldn't get a fuzzer base class" << endl;
87 return NULL;
88 }
89 if (!fuzzer->LoadTargetComponent(dll_file_name)) return NULL;
90
91 for (const vts::FunctionSpecificationMessage& func_msg : iface_spec_msg.api()) {
92 cout << "Add a job " << func_msg.name() << endl;
93 FunctionSpecificationMessage* func_msg_copy = func_msg.New();
94 func_msg_copy->CopyFrom(func_msg);
95 job_queue_.push(make_pair(func_msg_copy, fuzzer));
96 }
97 return fuzzer;
98}
99
100
Keun Soo Yim08400372016-03-03 13:28:51 -0800101bool SpecificationBuilder::Process(
102 const char* dll_file_name,
103 const char* spec_lib_file_path,
104 int target_class,
105 int target_type,
106 float target_version) {
107 vts::InterfaceSpecificationMessage* interface_specification_message =
108 FindInterfaceSpecification(target_class, target_type, target_version);
109 if (!interface_specification_message) {
110 cerr << __FUNCTION__ <<
111 ": no interface specification file found for "
112 << "class " << target_class
113 << " type " << target_type
114 << " version " << target_version << endl;
115 return false;
116 }
Keun Soo Yim08400372016-03-03 13:28:51 -0800117
Keun Soo Yim2ee90792016-04-27 14:53:54 -0700118 if (!wrapper_.LoadInterfaceSpecificationLibrary(spec_lib_file_path)) {
Keun Soo Yim08400372016-03-03 13:28:51 -0800119 return false;
120 }
Keun Soo Yim2ee90792016-04-27 14:53:54 -0700121
122 if (!GetFuzzerBaseAndAddAllFunctionsToQueue(
123 *interface_specification_message, dll_file_name)) return false;
124
Keun Soo Yim8103c912016-04-22 20:07:13 -0700125 for (int i = 0; i < epoch_count_; i++) {
Keun Soo Yim2ee90792016-04-27 14:53:54 -0700126 // by default, breath-first-searching is used.
127 if (job_queue_.empty()) {
128 cout << "no more job to process; stopping after epoch " << i << endl;
129 break;
130 }
131
132 pair<vts::FunctionSpecificationMessage*, FuzzerBase*> curr_job =
133 job_queue_.front();
134 job_queue_.pop();
135
136 vts::FunctionSpecificationMessage* func_msg = curr_job.first;
137 FuzzerBase* func_fuzzer = curr_job.second;
138
Keun Soo Yimc5d092a2016-04-28 16:51:56 +0000139 void* result;
Keun Soo Yim2ee90792016-04-27 14:53:54 -0700140 cout << "Iteration " << (i + 1) << " Function " << func_msg->name() << endl;
141 func_fuzzer->Fuzz(*func_msg, &result);
142 cout << __FUNCTION__ << " " << __LINE__ << endl;
143 if (func_msg->return_type().has_aggregate_type()) {
144 if (result != NULL) {
145 // loads that interface spec and enqueues all functions.
146 cout << __FUNCTION__ << " return type: "
147 << func_msg->return_type().aggregate_type() << endl;
148 string submodule_name = func_msg->return_type().aggregate_type();
149 while (!submodule_name.empty()
150 && (std::isspace(submodule_name.back())
151 || submodule_name.back() == '*' )) {
152 submodule_name.pop_back();
153 }
154 vts::InterfaceSpecificationMessage* iface_spec_msg =
155 FindInterfaceSpecification(
156 target_class, target_type, target_version, submodule_name);
157 if (iface_spec_msg) {
158 cout << __FUNCTION__ << " submodule found - " << submodule_name << endl;
159 if (!GetFuzzerBaseAndAddAllFunctionsToQueue(
160 *iface_spec_msg, dll_file_name)) {
161 return false;
162 }
163 } else {
164 cout << __FUNCTION__ << " submodule not found - " << submodule_name << endl;
165 }
166 } else {
167 cout << __FUNCTION__ << " return value = NULL" << endl;
168 }
169 }
Keun Soo Yim08400372016-03-03 13:28:51 -0800170 }
Keun Soo Yim2ee90792016-04-27 14:53:54 -0700171
Keun Soo Yim08400372016-03-03 13:28:51 -0800172 return true;
173}
174
Keun Soo Yim08400372016-03-03 13:28:51 -0800175} // namespace vts
176} // namespace android