1 /*
2  * Copyright 2023 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 "Common.h"
18 #include "Enumerator.h"
19 #include "HalCamera.h"
20 #include "MockEvsHal.h"
21 #include "utils/include/Utils.h"
22 
23 #include <fuzzbinder/libbinder_ndk_driver.h>
24 #include <fuzzer/FuzzedDataProvider.h>
25 
26 #include <sys/time.h>
27 
28 #include <iostream>
29 
30 namespace {
31 
32 using aidl::android::automotive::evs::implementation::HalCamera;
33 using aidl::android::automotive::evs::implementation::initializeMockEvsHal;
34 using aidl::android::automotive::evs::implementation::MockEvsHal;
35 using aidl::android::automotive::evs::implementation::NiceMockEvsCamera;
36 using aidl::android::automotive::evs::implementation::openFirstCamera;
37 using aidl::android::automotive::evs::implementation::Utils;
38 using aidl::android::automotive::evs::implementation::VirtualCamera;
39 using aidl::android::hardware::automotive::evs::BufferDesc;
40 using aidl::android::hardware::automotive::evs::CameraDesc;
41 using aidl::android::hardware::automotive::evs::CameraParam;
42 using aidl::android::hardware::automotive::evs::EvsEventDesc;
43 using aidl::android::hardware::automotive::evs::EvsEventType;
44 using aidl::android::hardware::automotive::evs::IEvsCamera;
45 using aidl::android::hardware::automotive::evs::IEvsEnumerator;
46 using aidl::android::hardware::automotive::evs::Stream;
47 
48 enum EvsFuzzFuncs {
49     EVS_FUZZ_MAKE_VIRTUAL_CAMERA = 0,    // verify makeVirtualCamera
50     EVS_FUZZ_OWN_VIRTUAL_CAMERA,         // verify ownVirtualCamera
51     EVS_FUZZ_DISOWN_VIRTUAL_CAMERA,      // verify disownVirtualCamera
52     EVS_FUZZ_GET_CLIENT_COUNT,           // verify getClientCount
53     EVS_FUZZ_GET_ID,                     // verify getId
54     EVS_FUZZ_GET_STREAM_CONFIG,          // verify getStreamConfig
55     EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT,    // verify changeFramesInFlight
56     EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT_1,  // verify overloaded changeFramesInFlight
57     EVS_FUZZ_REQUEST_NEW_FRAME,          // verify requestNewFrame
58     EVS_FUZZ_CLIENT_STREAM_STARTING,     // verify clientStreamStarting
59     EVS_FUZZ_CLIENT_STREAM_ENDING,       // verify clientStreamEnding
60     EVS_FUZZ_GET_STATS,                  // verify getStats
61     EVS_FUZZ_GET_STREAM_CONFIGURATION,   // verify getStreamConfiguration
62     EVS_FUZZ_BASE_ENUM,                  // verify common functions
63 };
64 
getCurrentTimeStamp()65 int64_t getCurrentTimeStamp() {
66     struct timeval tp;
67     gettimeofday(&tp, NULL);
68     int64_t ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
69     return ms;
70 }
71 
72 const int kMaxFuzzerConsumedBytes = 12;
73 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)74 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
75     FuzzedDataProvider fdp(data, size);
76 
77     std::shared_ptr<MockEvsHal> mockEvsHal = initializeMockEvsHal();
78     EXPECT_NE(mockEvsHal, nullptr);
79 
80     std::shared_ptr<IEvsCamera> mockHwCamera = openFirstCamera(mockEvsHal);
81     EXPECT_NE(mockHwCamera, nullptr);
82 
83     std::shared_ptr<HalCamera> halCamera = ndk::SharedRefBase::make<HalCamera>(mockHwCamera);
84     EXPECT_NE(halCamera, nullptr);
85     std::vector<std::shared_ptr<VirtualCamera>> virtualCameras;
86     std::vector<BufferDesc> buffers;
87 
88     while (fdp.remaining_bytes() > kMaxFuzzerConsumedBytes) {
89         switch (fdp.ConsumeIntegralInRange<uint32_t>(0, EVS_FUZZ_API_SUM)) {
90             case EVS_FUZZ_MAKE_VIRTUAL_CAMERA: {
91                 LOG(DEBUG) << "EVS_FUZZ_MAKE_VIRTUAL_CAMERA";
92                 std::shared_ptr<VirtualCamera> virtualCamera = halCamera->makeVirtualCamera();
93                 virtualCameras.emplace_back(virtualCamera);
94                 break;
95             }
96             case EVS_FUZZ_OWN_VIRTUAL_CAMERA: {
97                 LOG(DEBUG) << "EVS_FUZZ_OWN_VIRTUAL_CAMERA";
98                 if (!virtualCameras.empty()) {
99                     uint32_t whichCam =
100                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
101                     halCamera->ownVirtualCamera(virtualCameras[whichCam]);
102                 }
103                 break;
104             }
105             case EVS_FUZZ_DISOWN_VIRTUAL_CAMERA: {
106                 LOG(DEBUG) << "EVS_FUZZ_DISOWN_VIRTUAL_CAMERA";
107                 if (!virtualCameras.empty()) {
108                     uint32_t whichCam =
109                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
110                     halCamera->disownVirtualCamera(virtualCameras[whichCam].get());
111                 }
112                 break;
113             }
114             case EVS_FUZZ_GET_HW_CAMERA: {
115                 LOG(DEBUG) << "EVS_FUZZ_GET_HW_CAMERA";
116                 halCamera->getHwCamera();
117                 break;
118             }
119             case EVS_FUZZ_GET_CLIENT_COUNT: {
120                 LOG(DEBUG) << "EVS_FUZZ_GET_CLIENT_COUNT";
121                 halCamera->getClientCount();
122                 break;
123             }
124             case EVS_FUZZ_GET_ID: {
125                 LOG(DEBUG) << "EVS_FUZZ_GET_ID";
126                 halCamera->getId();
127                 break;
128             }
129             case EVS_FUZZ_GET_STREAM_CONFIG: {
130                 LOG(DEBUG) << "EVS_FUZZ_GET_STREAM_CONFIG";
131                 halCamera->getStreamConfig();
132                 break;
133             }
134             case EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT: {
135                 LOG(DEBUG) << "EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT";
136                 uint32_t delta = fdp.ConsumeIntegral<int32_t>();
137                 halCamera->changeFramesInFlight(delta);
138                 break;
139             }
140             case EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT_1: {
141                 LOG(DEBUG) << "EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT_1";
142                 std::vector<BufferDesc> buffers;
143                 int32_t delta = 0;
144                 halCamera->changeFramesInFlight(buffers, &delta);
145                 break;
146             }
147             case EVS_FUZZ_REQUEST_NEW_FRAME: {
148                 LOG(DEBUG) << "EVS_FUZZ_REQUEST_NEW_FRAME";
149                 if (!virtualCameras.empty()) {
150                     uint32_t whichCam =
151                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
152                     halCamera->requestNewFrame(virtualCameras[whichCam], getCurrentTimeStamp());
153                 }
154                 break;
155             }
156             case EVS_FUZZ_CLIENT_STREAM_STARTING: {
157                 LOG(DEBUG) << "EVS_FUZZ_CLIENT_STREAM_STARTING";
158                 halCamera->clientStreamStarting();
159                 break;
160             }
161             case EVS_FUZZ_CLIENT_STREAM_ENDING: {
162                 LOG(DEBUG) << "EVS_FUZZ_CLIENT_STREAM_ENDING";
163                 if (!virtualCameras.empty()) {
164                     uint32_t whichCam =
165                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
166                     halCamera->clientStreamEnding(virtualCameras[whichCam].get());
167                 }
168                 break;
169             }
170             case EVS_FUZZ_DONE_WITH_FRAME: {
171                 LOG(DEBUG) << "EVS_FUZZ_DONE_WITH_FRAME";
172                 if (!buffers.empty()) {
173                     uint32_t whichBuffer =
174                             fdp.ConsumeIntegralInRange<uint32_t>(0, buffers.size() - 1);
175                     halCamera->doneWithFrame(
176                             Utils::dupBufferDesc(buffers[whichBuffer], /* doDup= */ true));
177                 }
178                 break;
179             }
180             case EVS_FUZZ_SET_PRIMARY: {
181                 LOG(DEBUG) << "EVS_FUZZ_SET_PRIMARY";
182                 if (!virtualCameras.empty()) {
183                     uint32_t whichCam =
184                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
185                     halCamera->setPrimaryClient(virtualCameras[whichCam]);
186                 }
187                 break;
188             }
189             case EVS_FUZZ_FORCE_PRIMARY: {
190                 LOG(DEBUG) << "EVS_FUZZ_FORCE_PRIMARY";
191                 if (!virtualCameras.empty()) {
192                     uint32_t whichCam =
193                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
194                     halCamera->forcePrimaryClient(virtualCameras[whichCam]);
195                 }
196                 break;
197             }
198             case EVS_FUZZ_UNSET_PRIMARY: {
199                 LOG(DEBUG) << "EVS_FUZZ_UNSET_PRIMARY";
200                 if (!virtualCameras.empty()) {
201                     uint32_t whichCam =
202                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
203                     halCamera->unsetPrimaryClient(virtualCameras[whichCam].get());
204                 }
205                 break;
206             }
207             case EVS_FUZZ_SET_PARAMETER: {
208                 LOG(DEBUG) << "EVS_FUZZ_SET_PARAMETER";
209                 if (!virtualCameras.empty()) {
210                     uint32_t whichCam =
211                             fdp.ConsumeIntegralInRange<uint32_t>(0, virtualCameras.size() - 1);
212                     uint32_t whichParam = fdp.ConsumeIntegralInRange<
213                             uint32_t>(0, static_cast<uint32_t>(CameraParam::ABSOLUTE_ZOOM));
214                     int32_t value = fdp.ConsumeIntegral<int32_t>();
215                     halCamera->setParameter(virtualCameras[whichCam],
216                                             static_cast<CameraParam>(whichParam), &value);
217                 }
218                 break;
219             }
220             case EVS_FUZZ_GET_PARAMETER: {
221                 LOG(DEBUG) << "EVS_FUZZ_GET_PARAMETER";
222                 uint32_t whichParam =
223                         fdp.ConsumeIntegralInRange<uint32_t>(0,
224                                                              static_cast<uint32_t>(
225                                                                      CameraParam::ABSOLUTE_ZOOM));
226                 int32_t value = fdp.ConsumeIntegral<int32_t>();
227                 halCamera->getParameter(static_cast<CameraParam>(whichParam), &value);
228                 break;
229             }
230             case EVS_FUZZ_GET_STATS: {
231                 LOG(DEBUG) << "EVS_FUZZ_GET_STATS";
232                 halCamera->getStats();
233                 break;
234             }
235             case EVS_FUZZ_GET_STREAM_CONFIGURATION: {
236                 LOG(DEBUG) << "EVS_FUZZ_GET_STREAM_CONFIGURATION";
237                 halCamera->getStreamConfiguration();
238                 break;
239             }
240             case EVS_FUZZ_DELIVER_FRAME: {
241                 LOG(DEBUG) << "EVS_FUZZ_DELIVER_FRAME";
242                 BufferDesc buffer, duped;
243                 buffer.bufferId = fdp.ConsumeIntegral<int32_t>();
244 
245                 std::vector<BufferDesc> buffersToSend(1);
246                 buffersToSend.push_back(Utils::dupBufferDesc(buffer, /* doDup= */ true));
247                 halCamera->deliverFrame(buffersToSend);
248                 buffers.emplace_back(std::move(buffer));
249                 break;
250             }
251             case EVS_FUZZ_NOTIFY: {
252                 LOG(DEBUG) << "EVS_FUZZ_NOTIFY";
253                 EvsEventDesc event;
254                 uint32_t type =
255                         fdp.ConsumeIntegralInRange<uint32_t>(0,
256                                                              static_cast<uint32_t>(
257                                                                      EvsEventType::STREAM_ERROR));
258                 event.aType = static_cast<EvsEventType>(type);
259                 // TODO(b/160824438) let's comment this for now because of the failure.
260                 // If virtualCamera does not call startVideoStream, and notify(1) is called
261                 // it will fail.
262                 // halCamera->notify(event);
263                 break;
264             }
265             default:
266                 LOG(ERROR) << "Unexpected option, aborting...";
267                 break;
268         }
269     }
270     return 0;
271 }
272 
273 }  // namespace
274