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