1 /*
2 * Copyright 2020 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 <fuzzer/FuzzedDataProvider.h>
18 #include <hidl/HidlTransportSupport.h>
19 #include <stdlib.h>
20 #include <sys/time.h>
21 #include <iostream>
22 #include "Common.h"
23 #include "Enumerator.h"
24 #include "HalDisplay.h"
25 #include "MockHWEnumerator.h"
26
27 using android::hardware::configureRpcThreadpool;
28 using android::hardware::joinRpcThreadpool;
29
30 namespace android {
31 namespace automotive {
32 namespace evs {
33 namespace V1_1 {
34 namespace implementation {
35
36 namespace {
37
38 enum EvsFuzzFuncs {
39 EVS_FUZZ_GET_CAMERA_LIST, // verify getCameraList
40 EVS_FUZZ_OPEN_CAMERA, // verify openCamera
41 EVS_FUZZ_CLOSE_CAMERA, // verify closeCamera
42 EVS_FUZZ_OPEN_DISPLAY, // verify openDisplay
43 EVS_FUZZ_CLOSE_DISPLAY, // verify closeDisplay
44 EVS_FUZZ_GET_DISPLAY_STATE, // verify getDisplayState
45 EVS_FUZZ_GET_CAMERA_LIST_1_1, // verify getCameraList_1_1
46 EVS_FUZZ_OPEN_CAMERA_1_1, // verify openCamera_1_1
47 EVS_FUZZ_IS_HARDWARE, // verify isHardware
48 EVS_FUZZ_GET_DISPLAY_LIST, // verify getDisplayIdList
49 EVS_FUZZ_OPEN_DISPLAY_1_1, // verify openDisplay_1_1
50 EVS_FUZZ_GET_ULTRASONICS_ARRAY_LIST, // verify getUltrasonicsArrayList
51 EVS_FUZZ_OPEN_ULTRASONICS_ARRAY, // verify openUltrasonicsArray
52 EVS_FUZZ_CLOSE_ULTRASONICS_ARRAY, // verify closeUltrasonicsArray
53 EVS_FUZZ_API_SUM
54 };
55
56 const int kMaxFuzzerConsumedBytes = 12;
57
58
59 static sp<IEvsEnumerator_1_1> sMockHWEnumerator;
60 static sp<Enumerator> sEnumerator;
61
DoInitialization()62 bool DoInitialization() {
63 android::hardware::details::setTrebleTestingOverride(true);
64 configureRpcThreadpool(2, false /* callerWillNotJoin */);
65
66 // Prepare for the HWEnumerator service
67 sMockHWEnumerator = new MockHWEnumerator();
68 status_t status = sMockHWEnumerator->registerAsService(kMockHWEnumeratorName);
69 if (status != OK) {
70 std::cerr << "Could not register service " << kMockHWEnumeratorName
71 << " status = " << status
72 << " - quitting from LLVMFuzzerInitialize" << std::endl;
73 exit(2);
74 }
75
76 return true;
77 }
78
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)79 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
80 FuzzedDataProvider fdp(data, size);
81
82 vector<sp<IEvsCamera_1_0>> vVirtualCameras;
83 vector<sp<IEvsDisplay_1_0>> vDisplays;
84
85 // Inititialize the enumerator that we are going to test
86 static bool initialized = DoInitialization();
87 sEnumerator = new Enumerator();
88 if (!initialized || !sEnumerator->init(kMockHWEnumeratorName)) {
89 std::cerr << "Failed to connect to hardware service"
90 << "- quitting from LLVMFuzzerInitialize" << std::endl;
91 exit(1);
92 }
93
94 while (fdp.remaining_bytes() > kMaxFuzzerConsumedBytes) {
95 switch (fdp.ConsumeIntegralInRange<uint32_t>(0, EVS_FUZZ_API_SUM)) {
96 case EVS_FUZZ_GET_CAMERA_LIST: {
97 LOG(DEBUG) << "EVS_FUZZ_GET_CAMERA_LIST";
98 sEnumerator->getCameraList([](auto list) {});
99 break;
100 }
101 case EVS_FUZZ_OPEN_CAMERA: {
102 LOG(DEBUG) << "EVS_FUZZ_OPEN_CAMERA";
103 uint64_t whichCam =
104 fdp.ConsumeIntegralInRange<uint64_t>(startMockHWCameraId,
105 endMockHWCameraId-1);
106 hidl_string camStr = std::to_string(whichCam);
107 sp<IEvsCamera_1_0> virtualCam = sEnumerator->openCamera(camStr);
108 if (virtualCam != nullptr) {
109 vVirtualCameras.emplace_back(virtualCam);
110 }
111 break;
112 }
113 case EVS_FUZZ_CLOSE_CAMERA: {
114 LOG(DEBUG) << "EVS_FUZZ_CLOSE_CAMERA";
115 if (!vVirtualCameras.empty()) {
116 sp<IEvsCamera_1_0> cam = vVirtualCameras.back();
117 sEnumerator->closeCamera(cam);
118 vVirtualCameras.pop_back();
119 }
120 break;
121 }
122 case EVS_FUZZ_OPEN_DISPLAY: {
123 LOG(DEBUG) << "EVS_FUZZ_OPEN_DISPLAY";
124 sp<IEvsDisplay_1_0> display = sEnumerator->openDisplay();
125 if (display != nullptr) {
126 vDisplays.emplace_back(display);
127 }
128 break;
129 }
130 case EVS_FUZZ_CLOSE_DISPLAY: {
131 LOG(DEBUG) << "EVS_FUZZ_CLOSE_DISPLAY";
132 if (!vDisplays.empty()) {
133 sp<IEvsDisplay_1_0> display = vDisplays.back();
134 sEnumerator->closeDisplay(display);
135 vDisplays.pop_back();
136 }
137 break;
138 }
139 case EVS_FUZZ_GET_DISPLAY_STATE: {
140 LOG(DEBUG) << "EVS_FUZZ_GET_DISPLAY_STATE";
141 sEnumerator->getDisplayState();
142 break;
143 }
144 case EVS_FUZZ_GET_CAMERA_LIST_1_1: {
145 LOG(DEBUG) << "EVS_FUZZ_GET_CAMERA_LIST_1_1";
146 sEnumerator->getCameraList_1_1([](auto cams) {});
147 break;
148 }
149 case EVS_FUZZ_OPEN_CAMERA_1_1: {
150 LOG(DEBUG) << "EVS_FUZZ_OPEN_CAMERA_1_1";
151 uint64_t whichCam =
152 fdp.ConsumeIntegralInRange<uint64_t>(startMockHWCameraId,
153 endMockHWCameraId-1);
154 hidl_string camStr = std::to_string(whichCam);
155 Stream streamCfg = {};
156 sp<IEvsCamera_1_1> virtualCam = sEnumerator->openCamera_1_1(camStr, streamCfg);
157 if (virtualCam != nullptr) {
158 vVirtualCameras.emplace_back(virtualCam);
159 }
160 break;
161 }
162 case EVS_FUZZ_IS_HARDWARE: {
163 LOG(DEBUG) << "EVS_FUZZ_IS_HARDWARE";
164 sEnumerator->isHardware();
165 break;
166 }
167 case EVS_FUZZ_GET_DISPLAY_LIST: {
168 LOG(DEBUG) << "EVS_FUZZ_GET_DISPLAY_LIST";
169 sEnumerator->getDisplayIdList([](auto list) {});
170 break;
171 }
172 case EVS_FUZZ_OPEN_DISPLAY_1_1: {
173 LOG(DEBUG) << "EVS_FUZZ_OPEN_DISPLAY_1_1";
174 uint64_t whichDisp =
175 fdp.ConsumeIntegralInRange<uint64_t>(startMockHWDisplayId,
176 endMockHWDisplayId-1);
177 // port is the same as display in this test
178 sp<IEvsDisplay_1_1> display = sEnumerator->openDisplay_1_1(
179 static_cast<uint8_t>(whichDisp));
180 if (display != nullptr) {
181 vDisplays.emplace_back(display);
182 }
183 break;
184 }
185 case EVS_FUZZ_GET_ULTRASONICS_ARRAY_LIST: {
186 LOG(DEBUG) << "EVS_FUZZ_GET_ULTRASONICS_ARRAY_LIST";
187 sEnumerator->getUltrasonicsArrayList([](auto list) {});
188 break;
189 }
190 case EVS_FUZZ_OPEN_ULTRASONICS_ARRAY: {
191 LOG(DEBUG) << "EVS_FUZZ_OPEN_ULTRASONICS_ARRAY";
192 // TODO(b/162465548) replace this once implementation is ready
193 sEnumerator->openUltrasonicsArray("");
194 break;
195 }
196 case EVS_FUZZ_CLOSE_ULTRASONICS_ARRAY: {
197 LOG(DEBUG) << "EVS_FUZZ_CLOSE_ULTRASONICS_ARRAY";
198 // TODO(b/162465548) replace this once implementation is ready
199 sEnumerator->closeUltrasonicsArray(nullptr);
200 break;
201 }
202 default:
203 LOG(ERROR) << "Unexpected option, aborting...";
204 break;
205 }
206 }
207
208 // Explicitly destroy the Enumerator
209 sEnumerator = nullptr;
210 return 0;
211 }
212
213 } // namespace
214 } // namespace implementation
215 } // namespace V1_1
216 } // namespace evs
217 } // namespace automotive
218 } // namespace android
219