1 /*
2  * Copyright (C) 2022 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 #include "AutomotiveSvV1_0Fuzzer.h"
19 #include <SurroundViewStream.h>
20 #include <android/hidl/allocator/1.0/IAllocator.h>
21 #include <hidlmemory/mapping.h>
22 
23 namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
24 
25 using ::android::hardware::hidl_memory;
26 using ::android::hardware::hidl_string;
27 using ::android::hardware::hidl_vec;
28 using ::android::hidl::allocator::V1_0::IAllocator;
29 
30 constexpr uint32_t kMinConfigDimension = 0;
31 constexpr uint32_t kMaxConfigDimension = 4096;
32 constexpr uint32_t kVertexByteSize = (3 * sizeof(float)) + 4;
33 constexpr uint32_t kIdByteSize = 2;
34 constexpr size_t kMaxCharacters = 30;
35 constexpr size_t kMaxVertices = 10;
36 constexpr size_t kMaxCameraPoints = 10;
37 constexpr size_t kMaxViews = 10;
38 constexpr size_t kMaxOverlays = 10;
39 constexpr size_t kMinSvBuffers = 0;
40 constexpr size_t kMaxSvBuffers = 10;
41 
invoke2dSessionAPI()42 void SurroundViewFuzzer::invoke2dSessionAPI() {
43     sp<ISurroundView2dSession> surroundView2dSession;
44     sp<SurroundViewStream> handler;
45     mSurroundViewService->start2dSession(
46             [&surroundView2dSession](const sp<ISurroundView2dSession>& session, SvResult result) {
47                 if (result == SvResult::OK) {
48                     surroundView2dSession = session;
49                 }
50             });
51 
52     if (surroundView2dSession && !mIs2dStreamStarted) {
53         handler = sp<SurroundViewStream>::make(surroundView2dSession);
54         if (surroundView2dSession->startStream(handler) == SvResult::OK) {
55             mIs2dStreamStarted = true;
56         }
57     }
58 
59     while (mFuzzedDataProvider.remaining_bytes() > 0) {
60         auto surroundView2dFunc = mFuzzedDataProvider.PickValueInArray<
61                 const std::function<void()>>({
62                 [&]() {
63                     if (surroundView2dSession) {
64                         surroundView2dSession->get2dMappingInfo(
65                                 []([[maybe_unused]] Sv2dMappingInfo info) {});
66                     }
67                 },
68                 [&]() {
69                     if (surroundView2dSession && mIs2dStreamStarted) {
70                         Sv2dConfig config;
71                         config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
72                                 kMinConfigDimension, kMaxConfigDimension);
73                         if (mFuzzedDataProvider.ConsumeBool()) {
74                             config.blending = static_cast<SvQuality>(
75                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
76                         } else {
77                             config.blending = mFuzzedDataProvider.ConsumeBool() ? (SvQuality::HIGH)
78                                                                                 : (SvQuality::LOW);
79                         }
80                         surroundView2dSession->set2dConfig(config);
81                     }
82                 },
83                 [&]() {
84                     if (surroundView2dSession) {
85                         surroundView2dSession->get2dConfig([&](Sv2dConfig) {});
86                     }
87                 },
88                 [&]() {
89                     if (surroundView2dSession) {
90                         hidl_vec<Point2dInt> points2dCamera;
91                         const size_t camPoints = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
92                                 1, kMaxCameraPoints);
93                         points2dCamera.resize(camPoints);
94                         for (size_t i = 0; i < camPoints; ++i) {
95                             points2dCamera[i].x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
96                             points2dCamera[i].y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
97                         }
98 
99                         hidl_vec<hidl_string> cameraIds;
100                         mSurroundViewService->getCameraIds(
101                                 [&cameraIds](const hidl_vec<hidl_string>& camIds) {
102                                     cameraIds = camIds;
103                                 });
104                         hidl_string cameraId;
105                         if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
106                             const size_t cameraIndex =
107                                     mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
108                                             0, cameraIds.size() - 1);
109                             cameraId = cameraIds[cameraIndex];
110                         } else {
111                             cameraId =
112                                     mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
113                         }
114                         surroundView2dSession->projectCameraPoints(
115                                 points2dCamera, cameraId,
116                                 []([[maybe_unused]] const hidl_vec<Point2dFloat>& outPoints) {});
117                     }
118                 },
119                 [&]() {
120                     if (surroundView2dSession) {
121                         SvFramesDesc frames;
122                         frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
123                         frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
124                         size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
125                                 kMinSvBuffers, kMaxSvBuffers);
126                         frames.svBuffers.resize(numSvBuffers);
127                         for (int i = 0; i < numSvBuffers; ++i) {
128                             frames.svBuffers[i].viewId =
129                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
130                             frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
131                             frames.svBuffers[i].hardwareBuffer.description[0] =
132                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
133                             frames.svBuffers[i].hardwareBuffer.description[1] =
134                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
135                         }
136                         surroundView2dSession->doneWithFrames(frames);
137                         for (int i = 0; i < numSvBuffers; ++i) {
138                             delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
139                         }
140                     }
141                 },
142                 [&]() {
143                     if (surroundView2dSession) {
144                         surroundView2dSession->stopStream();
145                         mIs2dStreamStarted = false;
146                     }
147                 },
148                 [&]() {
149                     SvResult result = mSurroundViewService->stop2dSession(
150                             mFuzzedDataProvider.ConsumeBool() ? surroundView2dSession : nullptr);
151                     if (result == SvResult::OK) {
152                         mIs2dStreamStarted = false;
153                     }
154                 },
155         });
156         surroundView2dFunc();
157     }
158 
159     if (surroundView2dSession && mIs2dStreamStarted) {
160         surroundView2dSession->stopStream();
161     }
162 
163     if (surroundView2dSession) {
164         mSurroundViewService->stop2dSession(surroundView2dSession);
165     }
166 }
167 
invoke3dSessionAPI()168 void SurroundViewFuzzer::invoke3dSessionAPI() {
169     sp<ISurroundView3dSession> surroundView3dSession;
170     sp<SurroundViewStream> handler;
171     mSurroundViewService->start3dSession(
172             [&surroundView3dSession](const sp<ISurroundView3dSession>& session, SvResult result) {
173                 if (result == SvResult::OK) {
174                     surroundView3dSession = session;
175                 }
176             });
177 
178     const size_t numViews = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxViews);
179     std::vector<View3d> views(numViews);
180     for (size_t i = 0; i < numViews; ++i) {
181         views[i].viewId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
182     }
183     surroundView3dSession->setViews(views);
184 
185     if (surroundView3dSession) {
186         handler = sp<SurroundViewStream>::make(surroundView3dSession);
187 
188         if (surroundView3dSession->startStream(handler) == SvResult::OK) {
189             mIs3dStreamStarted = true;
190         }
191     }
192     while (mFuzzedDataProvider.remaining_bytes() > 0) {
193         auto surroundView3dFunc = mFuzzedDataProvider.PickValueInArray<
194                 const std::function<void()>>({
195                 [&]() {
196                     if (surroundView3dSession) {
197                         const size_t numViews =
198                                 mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxViews);
199                         std::vector<View3d> views(numViews);
200                         for (size_t i = 0; i < numViews; ++i) {
201                             views[i].viewId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
202                         }
203                         surroundView3dSession->setViews(views);
204                     }
205                 },
206                 [&]() {
207                     if (surroundView3dSession && mIs3dStreamStarted) {
208                         Sv3dConfig config;
209                         config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
210                                 kMinConfigDimension, kMaxConfigDimension);
211                         config.height = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
212                                 kMinConfigDimension, kMaxConfigDimension);
213                         if (mFuzzedDataProvider.ConsumeBool()) {
214                             config.carDetails = static_cast<SvQuality>(
215                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
216                         } else {
217                             config.carDetails = mFuzzedDataProvider.ConsumeBool()
218                                                         ? (SvQuality::HIGH)
219                                                         : (SvQuality::LOW);
220                         }
221                         surroundView3dSession->set3dConfig(config);
222                     }
223                 },
224                 [&]() {
225                     if (surroundView3dSession) {
226                         surroundView3dSession->get3dConfig([&](Sv3dConfig) {});
227                     }
228                 },
229                 [&]() {
230                     if (surroundView3dSession) {
231                         Point2dInt cameraPoint;
232                         cameraPoint.x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
233                         cameraPoint.y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
234                         std::vector<Point2dInt> cameraPoints = {cameraPoint};
235                         hidl_vec<hidl_string> cameraIds;
236                         mSurroundViewService->getCameraIds(
237                                 [&cameraIds](const hidl_vec<hidl_string>& camIds) {
238                                     cameraIds = camIds;
239                                 });
240                         hidl_string cameraId;
241                         if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
242                             const size_t cameraIndex =
243                                     mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
244                                             0, cameraIds.size() - 1);
245                             cameraId = cameraIds[cameraIndex];
246                         } else {
247                             cameraId =
248                                     mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
249                         }
250                         std::vector<Point3dFloat> points3d;
251                         surroundView3dSession->projectCameraPointsTo3dSurface(
252                                 cameraPoints, cameraId,
253                                 [&points3d]([[maybe_unused]] const hidl_vec<Point3dFloat>&
254                                                     points3dproj) { points3d = points3dproj; });
255                     }
256                 },
257                 [&]() {
258                     if (surroundView3dSession) {
259                         // success case
260                         surroundView3dSession->updateOverlays(mOverlaysdata);
261                     }
262                 },
263                 [&]() {
264                     if (surroundView3dSession) {
265                         initSampleOverlaysData();
266                         // Fail with ID mismatch
267                         // Set id of second overlay in shared memory to 2 (expected is 1).
268                         auto& overlaysDescVector = mOverlaysdata.overlaysMemoryDesc;
269                         auto& pIMemory = mMemory;
270                         int32_t indexPosition = mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
271                                 0, mNumOverlays - 1);
272                         int32_t mismatchedValueIndex =
273                                 mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
274                                         0, mNumOverlays - 1);
275                         setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, indexPosition,
276                                                  overlaysDescVector[mismatchedValueIndex].id);
277                         surroundView3dSession->updateOverlays(mOverlaysdata);
278                     }
279                 },
280                 [&]() {
281                     if (surroundView3dSession) {
282                         // Fail with NULL memory
283                         // Set shared memory to null.
284                         mOverlaysdata.overlaysMemory = hidl_memory();
285                         surroundView3dSession->updateOverlays(mOverlaysdata);
286                     }
287                 },
288                 [&]() {
289                     if (surroundView3dSession) {
290                         SvFramesDesc frames;
291                         frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
292                         frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
293                         size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
294                                 kMinSvBuffers, kMaxSvBuffers);
295                         frames.svBuffers.resize(numSvBuffers);
296                         for (int i = 0; i < numSvBuffers; ++i) {
297                             frames.svBuffers[i].viewId =
298                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
299                             frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
300                             frames.svBuffers[i].hardwareBuffer.description[0] =
301                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
302                             frames.svBuffers[i].hardwareBuffer.description[1] =
303                                     mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
304                         }
305                         surroundView3dSession->doneWithFrames(frames);
306                         for (int i = 0; i < numSvBuffers; ++i) {
307                             delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
308                         }
309                     }
310                 },
311                 [&]() {
312                     if (surroundView3dSession) {
313                         surroundView3dSession->stopStream();
314                         mIs3dStreamStarted = false;
315                     }
316                 },
317                 [&]() {
318                     SvResult result = mSurroundViewService->stop3dSession(
319                             mFuzzedDataProvider.ConsumeBool() ? surroundView3dSession : nullptr);
320                     if (result == SvResult::OK) {
321                         mIs3dStreamStarted = false;
322                     }
323                 },
324         });
325         surroundView3dFunc();
326     }
327     if (surroundView3dSession && mIs3dStreamStarted) {
328         surroundView3dSession->stopStream();
329     }
330 
331     if (surroundView3dSession) {
332         mSurroundViewService->stop3dSession(surroundView3dSession);
333     }
334 }
335 
process()336 void SurroundViewFuzzer::process() {
337     mFuzzedDataProvider.ConsumeBool() ? invoke2dSessionAPI() : invoke3dSessionAPI();
338 }
339 
getMappedSharedMemory(int32_t bytesSize)340 std::pair<hidl_memory, sp<IMemory>> SurroundViewFuzzer::getMappedSharedMemory(int32_t bytesSize) {
341     const auto nullResult = std::make_pair(hidl_memory(), nullptr);
342 
343     sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
344     if (ashmemAllocator.get() == nullptr) {
345         return nullResult;
346     }
347 
348     // Allocate shared memory.
349     hidl_memory hidlMemory;
350     bool allocateSuccess = false;
351     Return<void> result =
352             ashmemAllocator->allocate(bytesSize, [&](bool success, const hidl_memory& hidlMem) {
353                 if (!success) {
354                     return;
355                 }
356                 allocateSuccess = success;
357                 hidlMemory = hidlMem;
358             });
359 
360     // Check result of allocated memory.
361     if (!result.isOk() || !allocateSuccess) {
362         return nullResult;
363     }
364 
365     // Map shared memory.
366     sp<IMemory> pIMemory = mapMemory(hidlMemory);
367     if (pIMemory.get() == nullptr) {
368         return nullResult;
369     }
370 
371     return std::make_pair(hidlMemory, pIMemory);
372 }
373 
setIndexOfOverlaysMemory(const std::vector<OverlayMemoryDesc> & overlaysMemDesc,sp<IMemory> pIMemory,int32_t indexPosition,uint16_t indexValue)374 void SurroundViewFuzzer::setIndexOfOverlaysMemory(
375         const std::vector<OverlayMemoryDesc>& overlaysMemDesc, sp<IMemory> pIMemory,
376         int32_t indexPosition, uint16_t indexValue) {
377     // Count the number of vertices until the index.
378     int32_t totalVerticesCount = 0;
379     for (int32_t i = 0; i < indexPosition; ++i) {
380         totalVerticesCount += overlaysMemDesc[i].verticesCount;
381     }
382 
383     const int32_t indexBytePosition =
384             (indexPosition * kIdByteSize) + (kVertexByteSize * totalVerticesCount);
385 
386     uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer());
387     pSharedMemoryData += indexBytePosition;
388     uint16_t* pIndex16bit = (uint16_t*)pSharedMemoryData;
389 
390     // Modify shared memory.
391     pIMemory->update();
392     *pIndex16bit = indexValue;
393     pIMemory->commit();
394 }
395 
initSampleOverlaysData()396 void SurroundViewFuzzer::initSampleOverlaysData() {
397     const size_t mNumOverlays =
398             mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(kMinOverlays, kMaxOverlays);
399     mOverlaysdata.overlaysMemoryDesc.resize(mNumOverlays);
400 
401     int32_t sharedMemBytesSize = 0;
402     std::vector<OverlayMemoryDesc> overlaysDescVector = {};
403     OverlayMemoryDesc overlayMemDesc[mNumOverlays];
404     for (size_t i = 0; i < mNumOverlays; ++i) {
405         overlayMemDesc[i].id = i;
406         overlayMemDesc[i].verticesCount =
407                 mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxVertices);
408         overlayMemDesc[i].overlayPrimitive = mFuzzedDataProvider.ConsumeBool()
409                                                      ? (OverlayPrimitive::TRIANGLES)
410                                                      : (OverlayPrimitive::TRIANGLES_STRIP);
411         mOverlaysdata.overlaysMemoryDesc[i] = overlayMemDesc[i];
412 
413         sharedMemBytesSize += kIdByteSize + kVertexByteSize * overlayMemDesc[i].verticesCount;
414         overlaysDescVector.push_back(overlayMemDesc[i]);
415     }
416 
417     std::pair<hidl_memory, sp<IMemory>> sharedMem = getMappedSharedMemory(sharedMemBytesSize);
418     sp<IMemory> pIMemory = std::get<1>(sharedMem);
419     if (pIMemory.get() == nullptr) {
420         mOverlaysdata = OverlaysData();
421         mMemory = nullptr;
422         return;
423     }
424 
425     // Get pointer to shared memory data and set all bytes to 0.
426     uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer());
427     pIMemory->update();
428     memset(pSharedMemoryData, 0, sharedMemBytesSize);
429     pIMemory->commit();
430 
431     // Set indexes in shared memory.
432     for (size_t i = 0; i < mNumOverlays; ++i) {
433         setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, i, overlayMemDesc[i].id);
434     }
435 
436     mOverlaysdata.overlaysMemoryDesc = overlaysDescVector;
437     mOverlaysdata.overlaysMemory = std::get<0>(sharedMem);
438     mMemory = pIMemory;
439 }
440 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)441 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
442     if (size < 1) {
443         return 0;
444     }
445     SurroundViewFuzzer surroundViewFuzzer(data, size);
446     surroundViewFuzzer.process();
447     return 0;
448 }
449 }  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
450