blob: f1483b82bd4e933f1d7141a0447e47371a02c80d [file] [log] [blame]
Keun Soo Yimff902242016-03-03 16:23:38 -08001/*
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/*
Keun Soo Yimbf804532016-05-07 22:40:38 -070018 * Example usage (for angler 64-bit devices):
Keun Soo Yim1f340b92016-07-09 12:42:33 -070019 * $ 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
Keun Soo Yimbf804532016-05-07 22:40:38 -070023 *
Keun Soo Yim8e07a092016-05-04 16:30:35 -070024 * $ LD_LIBRARY_PATH=/data/local/tmp/64 ./fuzzer64 --class=hal --type=light \
Keun Soo Yim04431a92016-05-24 16:26:42 -070025 * --version=1.0 --spec_dir=/data/local/tmp/spec \
Keun Soo Yim8e07a092016-05-04 16:30:35 -070026 * /data/local/tmp/64/hal/lights.bullhead-vts.so
27 * $ LD_LIBRARY_PATH=/data/local/tmp/32 ./fuzzer32 --class=hal --type=light \
28 * --version=1.0 --spec_dir=/data/local/tmp/spec \
29 * /data/local/tmp/32/hal/camera.bullhead-vts.so
Keun Soo Yim04431a92016-05-24 16:26:42 -070030 *
Keun Soo Yimbf804532016-05-07 22:40:38 -070031 * Example usage (for GCE virtual devices):
Keun Soo Yim1f340b92016-07-09 12:42:33 -070032 * $ fuzzer --class=hal_conventional --type=light --version=1.0
33 * /system/lib/hw/lights.gce_x86.so
34 * $ fuzzer --class=hal_conventional --type=gps --version=1.0
35 * /system/lib/hw/gps.gce_x86.so
36 * $ fuzzer --class=hal_conventional --type=camera --version=2.1
37 * /system/lib/hw/camera.gce_x86.so
Keun Soo Yimff902242016-03-03 16:23:38 -080038 */
39
40#include <getopt.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <unistd.h>
45
46#include <algorithm>
Keun Soo Yimff902242016-03-03 16:23:38 -080047#include <iostream>
Keun Soo Yim1f340b92016-07-09 12:42:33 -070048#include <string>
Keun Soo Yimff902242016-03-03 16:23:38 -080049
Keun Soo Yimbf804532016-05-07 22:40:38 -070050#include "binder/VtsFuzzerBinderService.h"
Keun Soo Yimff902242016-03-03 16:23:38 -080051#include "specification_parser/InterfaceSpecificationParser.h"
52#include "specification_parser/SpecificationBuilder.h"
53
Keun Soo Yimbf804532016-05-07 22:40:38 -070054#include "BinderServer.h"
Keun Soo Yim14f22722016-06-29 09:49:38 -070055#include "SocketServer.h"
Keun Soo Yimbf804532016-05-07 22:40:38 -070056
Keun Soo Yimff902242016-03-03 16:23:38 -080057using namespace std;
58using namespace android;
59
60#define INTERFACE_SPEC_LIB_FILENAME "libvts_interfacespecification.so"
Keun Soo Yimfa7ea842016-05-03 16:44:14 -070061#define PASSED_MARKER "[ PASSED ]"
Keun Soo Yimff902242016-03-03 16:23:38 -080062
Keun Soo Yim8103c912016-04-22 20:07:13 -070063// the default epoch count where an epoch is the time for a fuzz test run
64// (e.g., a function call).
65static const int kDefaultEpochCount = 100;
Keun Soo Yimff902242016-03-03 16:23:38 -080066
67// Dumps usage on stderr.
68static void usage() {
69 fprintf(
70 stderr,
71 "Usage: fuzzer [options] <target HAL file path>\n"
72 "\n"
73 "Android fuzzer v0.1. To fuzz Android system.\n"
74 "\n"
75 "Options:\n"
76 "--help\n"
77 " Show this message.\n"
78 "\n"
79 "Recording continues until Ctrl-C is hit or the time limit is reached.\n"
80 "\n");
81}
82
Keun Soo Yimff902242016-03-03 16:23:38 -080083// Parses command args and kicks things off.
84int main(int argc, char* const argv[]) {
85 static const struct option longOptions[] = {
Keun Soo Yim1f340b92016-07-09 12:42:33 -070086 {"help", no_argument, NULL, 'h'},
87 {"class", required_argument, NULL, 'c'},
88 {"type", required_argument, NULL, 't'},
89 {"version", required_argument, NULL, 'v'},
90 {"epoch_count", required_argument, NULL, 'e'},
91 {"spec_dir", required_argument, NULL, 's'},
Keun Soo Yim14f22722016-06-29 09:49:38 -070092#ifndef VTS_AGENT_DRIVER_COMM_BINDER // socket
Keun Soo Yim1f340b92016-07-09 12:42:33 -070093 {"server_socket_path", optional_argument, NULL, 'f'},
Keun Soo Yim14f22722016-06-29 09:49:38 -070094#else // binder
Keun Soo Yim1f340b92016-07-09 12:42:33 -070095 {"service_name", required_argument, NULL, 'n'},
Keun Soo Yim14f22722016-06-29 09:49:38 -070096#endif
Keun Soo Yim1f340b92016-07-09 12:42:33 -070097 {"server", optional_argument, NULL, 'd'},
98 {"callback_socket_name", optional_argument, NULL, 'p'},
99 {NULL, 0, NULL, 0}};
Keun Soo Yimff902242016-03-03 16:23:38 -0800100 int target_class;
101 int target_type;
102 float target_version = 1.0;
Keun Soo Yim8103c912016-04-22 20:07:13 -0700103 int epoch_count = kDefaultEpochCount;
Keun Soo Yimff902242016-03-03 16:23:38 -0800104 string spec_dir_path(DEFAULT_SPEC_DIR_PATH);
Keun Soo Yimbf804532016-05-07 22:40:38 -0700105 bool server = false;
Keun Soo Yim14f22722016-06-29 09:49:38 -0700106#ifndef VTS_AGENT_DRIVER_COMM_BINDER // socket
Keun Soo Yima066dd52016-07-01 15:18:28 -0700107 string server_socket_path;
Keun Soo Yim14f22722016-06-29 09:49:38 -0700108#else // binder
Keun Soo Yim8e07a092016-05-04 16:30:35 -0700109 string service_name(VTS_FUZZER_BINDER_SERVICE_NAME);
Keun Soo Yim14f22722016-06-29 09:49:38 -0700110#endif
Keun Soo Yim6d8a16b2016-06-30 19:29:02 -0700111 string callback_socket_name;
Keun Soo Yimff902242016-03-03 16:23:38 -0800112
113 while (true) {
114 int optionIndex = 0;
115 int ic = getopt_long(argc, argv, "", longOptions, &optionIndex);
116 if (ic == -1) {
117 break;
118 }
119
120 switch (ic) {
121 case 'h':
122 usage();
123 return 0;
124 case 'c': {
125 string target_class_str = string(optarg);
126 transform(target_class_str.begin(), target_class_str.end(),
127 target_class_str.begin(), ::tolower);
Keun Soo Yim78446412016-06-16 14:30:13 -0700128 if (!strcmp(target_class_str.c_str(), "hal_conventional")) {
129 target_class = vts::HAL_CONVENTIONAL;
Keun Soo Yimff902242016-03-03 16:23:38 -0800130 } else {
131 target_class = 0;
132 }
133 break;
134 }
135 case 't': {
136 string target_type_str = string(optarg);
137 transform(target_type_str.begin(), target_type_str.end(),
138 target_type_str.begin(), ::tolower);
139 if (!strcmp(target_type_str.c_str(), "camera")) {
140 target_type = vts::CAMERA;
141 } else if (!strcmp(target_type_str.c_str(), "gps")) {
142 target_type = vts::GPS;
143 } else if (!strcmp(target_type_str.c_str(), "audio")) {
144 target_type = vts::AUDIO;
145 } else if (!strcmp(target_type_str.c_str(), "light")) {
146 target_type = vts::LIGHT;
147 } else {
148 target_type = 0;
149 }
150 break;
151 }
152 case 'v':
153 target_version = atof(optarg);
154 break;
Keun Soo Yima4a6d532016-06-08 09:11:40 -0700155 case 'p':
Keun Soo Yim6d8a16b2016-06-30 19:29:02 -0700156 callback_socket_name = string(optarg);
Keun Soo Yima4a6d532016-06-08 09:11:40 -0700157 break;
Keun Soo Yim8103c912016-04-22 20:07:13 -0700158 case 'e':
159 epoch_count = atoi(optarg);
160 if (epoch_count <= 0) {
161 fprintf(stderr, "epoch_count must be > 0");
162 return 2;
163 }
164 break;
Keun Soo Yimff902242016-03-03 16:23:38 -0800165 case 's':
166 spec_dir_path = string(optarg);
167 break;
Keun Soo Yim14f22722016-06-29 09:49:38 -0700168#ifndef VTS_AGENT_DRIVER_COMM_BINDER // socket
169 case 'f':
Keun Soo Yima066dd52016-07-01 15:18:28 -0700170 server_socket_path = string(optarg);
Keun Soo Yim14f22722016-06-29 09:49:38 -0700171 break;
172#else // binder
Keun Soo Yim8e07a092016-05-04 16:30:35 -0700173 case 'n':
174 service_name = string(optarg);
175 break;
Keun Soo Yim14f22722016-06-29 09:49:38 -0700176#endif
Keun Soo Yimbf804532016-05-07 22:40:38 -0700177 case 'd':
178 server = true;
179 break;
Keun Soo Yimff902242016-03-03 16:23:38 -0800180 default:
181 if (ic != '?') {
182 fprintf(stderr, "getopt_long returned unexpected value 0x%x\n", ic);
183 }
184 return 2;
185 }
186 }
187
Keun Soo Yim1f340b92016-07-09 12:42:33 -0700188 android::vts::SpecificationBuilder spec_builder(spec_dir_path, epoch_count,
189 callback_socket_name);
Keun Soo Yimbf804532016-05-07 22:40:38 -0700190 if (!server) {
Keun Soo Yimfeceb4d2016-05-11 20:01:00 -0700191 if (optind != argc - 1) {
192 fprintf(stderr, "Must specify output file (see --help).\n");
193 return 2;
194 }
195
Keun Soo Yim1f340b92016-07-09 12:42:33 -0700196 bool success =
197 spec_builder.Process(argv[optind], INTERFACE_SPEC_LIB_FILENAME,
198 target_class, target_type, target_version);
Keun Soo Yimbf804532016-05-07 22:40:38 -0700199 cout << "Result: " << success << endl;
200 if (success) {
201 cout << endl << PASSED_MARKER << endl;
202 }
203 } else {
Keun Soo Yim14f22722016-06-29 09:49:38 -0700204#ifndef VTS_AGENT_DRIVER_COMM_BINDER // socket
Keun Soo Yim1f340b92016-07-09 12:42:33 -0700205 android::vts::StartSocketServer(server_socket_path, spec_builder,
206 INTERFACE_SPEC_LIB_FILENAME);
Keun Soo Yim14f22722016-06-29 09:49:38 -0700207#else // binder
Keun Soo Yim1f340b92016-07-09 12:42:33 -0700208 android::vts::StartBinderServer(service_name, spec_builder,
209 INTERFACE_SPEC_LIB_FILENAME);
Keun Soo Yim14f22722016-06-29 09:49:38 -0700210#endif
Keun Soo Yimbf804532016-05-07 22:40:38 -0700211 }
Keun Soo Yimff902242016-03-03 16:23:38 -0800212 return 0;
213}