• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 /*
18  * Example usage (for angler 64-bit devices):
19  *  $ fuzzer --class=hal_conventional --type=light --version=1.0
20  * /system/lib64/hw/lights.angler.so
21  *  $ fuzzer --class=hal_conventional --type=gps --version=1.0
22  * /system/lib64/hw/gps.msm8994.so
23  *
24  *  $ LD_LIBRARY_PATH=/data/local/tmp/64 ./fuzzer64 --class=hal --type=light \
25  *    --version=1.0 --spec_dir=/data/local/tmp/spec \
26  *    /data/local/tmp/64/hal/lights.vts.so
27  *
28  * Example usage (for GCE virtual devices):
29  *  $ fuzzer --class=hal_conventional --type=light --version=1.0
30  * /system/lib/hw/lights.gce_x86.so
31  *  $ fuzzer --class=hal_conventional --type=gps --version=1.0
32  * /system/lib/hw/gps.gce_x86.so
33  */
34 
35 #include <getopt.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 
41 #include <algorithm>
42 #include <iostream>
43 #include <string>
44 
45 #include "binder/VtsFuzzerBinderService.h"
46 #include "specification_parser/InterfaceSpecificationParser.h"
47 #include "specification_parser/SpecificationBuilder.h"
48 #include "replayer/VtsHidlHalReplayer.h"
49 
50 #include "BinderServer.h"
51 #include "SocketServer.h"
52 
53 using namespace std;
54 using namespace android;
55 
56 #define INTERFACE_SPEC_LIB_FILENAME "libvts_interfacespecification.so"
57 #define PASSED_MARKER "[  PASSED  ]"
58 
59 // the default epoch count where an epoch is the time for a fuzz test run
60 // (e.g., a function call).
61 static const int kDefaultEpochCount = 100;
62 
63 // Dumps usage on stderr.
usage()64 static void usage() {
65   // TODO(zhuoyao): update the usage message.
66   fprintf(
67       stderr,
68       "Usage: fuzzer [options] <target HAL file path>\n"
69       "\n"
70       "Android fuzzer v0.1.  To fuzz Android system.\n"
71       "\n"
72       "Options:\n"
73       "--help\n"
74       "    Show this message.\n"
75       "\n"
76       "Recording continues until Ctrl-C is hit or the time limit is reached.\n"
77       "\n");
78 }
79 
80 // Parses command args and kicks things off.
main(int argc,char * const argv[])81 int main(int argc, char* const argv[]) {
82   static const struct option longOptions[] = {
83       {"help", no_argument, NULL, 'h'},
84       {"class", required_argument, NULL, 'c'},
85       {"type", required_argument, NULL, 't'},
86       {"version", required_argument, NULL, 'v'},
87       {"epoch_count", required_argument, NULL, 'e'},
88       {"spec_dir", required_argument, NULL, 's'},
89       {"target_package", optional_argument, NULL, 'k'},
90       {"target_component_name", optional_argument, NULL, 'n'},
91 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
92       {"server_socket_path", optional_argument, NULL, 'f'},
93 #else  // binder
94       {"service_name", required_argument, NULL, 'n'},
95 #endif
96       {"server", optional_argument, NULL, 'd'},
97       {"callback_socket_name", optional_argument, NULL, 'p'},
98       // TODO(zhuoyao):make mode a required_argument to support different
99       // execution mode. e.g.: fuzzer/driver/replayer.
100       {"mode", optional_argument, NULL, 'm'},
101       {"trace_path", optional_argument, NULL, 'r'},
102       {"spec_path", optional_argument, NULL, 'a'},
103       {"hal_service_name", optional_argument, NULL, 'j'},
104       {NULL, 0, NULL, 0}};
105   int target_class;
106   int target_type;
107   float target_version = 1.0;
108   int epoch_count = kDefaultEpochCount;
109   string spec_dir_path(DEFAULT_SPEC_DIR_PATH);
110   bool server = false;
111 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
112   string server_socket_path;
113 #else  // binder
114   string service_name(VTS_FUZZER_BINDER_SERVICE_NAME);
115 #endif
116   string target_package;
117   string target_component_name;
118   string callback_socket_name;
119   string mode;
120   string trace_path;
121   string spec_path;
122   string hal_service_name = "default";
123 
124   while (true) {
125     int optionIndex = 0;
126     int ic = getopt_long(argc, argv, "", longOptions, &optionIndex);
127     if (ic == -1) {
128       break;
129     }
130 
131     switch (ic) {
132       case 'h':
133         usage();
134         return 0;
135       case 'c': {
136         string target_class_str = string(optarg);
137         transform(target_class_str.begin(), target_class_str.end(),
138                   target_class_str.begin(), ::tolower);
139         if (!strcmp(target_class_str.c_str(), "hal_conventional")) {
140           target_class = vts::HAL_CONVENTIONAL;
141         } else if (!strcmp(target_class_str.c_str(), "hal_hidl")) {
142           target_class = vts::HAL_HIDL;
143         } else {
144           target_class = 0;
145         }
146         break;
147       }
148       case 't': {
149         string target_type_str = string(optarg);
150         transform(target_type_str.begin(), target_type_str.end(),
151                   target_type_str.begin(), ::tolower);
152         if (!strcmp(target_type_str.c_str(), "camera")) {
153           target_type = vts::CAMERA;
154         } else if (!strcmp(target_type_str.c_str(), "gps")) {
155           target_type = vts::GPS;
156         } else if (!strcmp(target_type_str.c_str(), "audio")) {
157           target_type = vts::AUDIO;
158         } else if (!strcmp(target_type_str.c_str(), "light")) {
159           target_type = vts::LIGHT;
160         } else {
161           target_type = 0;
162         }
163         break;
164       }
165       case 'v':
166         target_version = atof(optarg);
167         break;
168       case 'p':
169         callback_socket_name = string(optarg);
170         break;
171       case 'e':
172         epoch_count = atoi(optarg);
173         if (epoch_count <= 0) {
174           fprintf(stderr, "epoch_count must be > 0");
175           return 2;
176         }
177         break;
178       case 's':
179         spec_dir_path = string(optarg);
180         break;
181 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
182       case 'f':
183         server_socket_path = string(optarg);
184         break;
185 #else  // binder
186       case 'n':
187         service_name = string(optarg);
188         break;
189 #endif
190       case 'd':
191         server = true;
192         break;
193       case 'k':
194         target_package = string(optarg);
195         break;
196       case 'n':
197         target_component_name = string(optarg);
198         break;
199       case 'm':
200         mode = string(optarg);
201         break;
202       case 'r':
203         trace_path = string(optarg);
204         break;
205       case 'a':
206         spec_path = string(optarg);
207         break;
208       case 'j':
209         hal_service_name = string(optarg);
210         break;
211       default:
212         if (ic != '?') {
213           fprintf(stderr, "getopt_long returned unexpected value 0x%x\n", ic);
214         }
215         return 2;
216     }
217   }
218 
219   android::vts::SpecificationBuilder spec_builder(spec_dir_path, epoch_count,
220                                                   callback_socket_name);
221   if (!server) {
222     if (optind != argc - 1) {
223       fprintf(stderr, "Must specify output file (see --help).\n");
224       return 2;
225     }
226     bool success;
227     if (mode == "replay") {
228       android::vts::VtsHidlHalReplayer replayer(spec_path,
229                                                 callback_socket_name);
230       success = replayer.ReplayTrace(argv[optind], trace_path,
231                                      hal_service_name);
232     } else {
233       success = spec_builder.Process(argv[optind],INTERFACE_SPEC_LIB_FILENAME,
234                                      target_class, target_type, target_version,
235                                      target_package.c_str(),
236                                      target_component_name.c_str());
237     }
238     cout << "Result: " << success << endl;
239     if (success) {
240       cout << endl << PASSED_MARKER << endl;
241     }
242   } else {
243 #ifndef VTS_AGENT_DRIVER_COMM_BINDER  // socket
244     android::vts::StartSocketServer(server_socket_path, spec_builder,
245                                     INTERFACE_SPEC_LIB_FILENAME);
246 #else  // binder
247     android::vts::StartBinderServer(service_name, spec_builder,
248                                     INTERFACE_SPEC_LIB_FILENAME);
249 #endif
250   }
251   return 0;
252 }
253