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