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