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 #include <CameraMetadata.h>
18 #include <camera/StringUtils.h>
19 #include <camera2/CaptureRequest.h>
20 #include <fuzzer/FuzzedDataProvider.h>
21 #include <gui/Surface.h>
22 #include <gui/SurfaceComposerClient.h>
23 #include <gui/view/Surface.h>
24 #include <gui/Flags.h> // remove with WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
25 #include "camera2common.h"
26
27 using namespace std;
28 using namespace android;
29
30 constexpr int32_t kNonZeroRangeMin = 0;
31 constexpr int32_t kRangeMax = 1000;
32 constexpr int32_t kSizeMin = 1;
33 constexpr int32_t kSizeMax = 1000;
34
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)35 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
36 FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
37
38 sp<CaptureRequest> captureRequest = new CaptureRequest();
39 Parcel parcelCamCaptureReq;
40
41 size_t physicalCameraSettingsSize =
42 fdp.ConsumeIntegralInRange<size_t>(kNonZeroRangeMin, kRangeMax);
43 if (fdp.ConsumeBool()) {
44 parcelCamCaptureReq.writeInt32(physicalCameraSettingsSize);
45 }
46
47 for (size_t idx = 0; idx < physicalCameraSettingsSize; ++idx) {
48 string id = fdp.ConsumeRandomLengthString(kMaxBytes);
49 if (fdp.ConsumeBool()) {
50 parcelCamCaptureReq.writeString16(toString16(id));
51 }
52 CameraMetadata cameraMetadata;
53 if (fdp.ConsumeBool()) {
54 cameraMetadata = CameraMetadata();
55 } else {
56 size_t entryCapacity = fdp.ConsumeIntegralInRange<size_t>(kNonZeroRangeMin, kRangeMax);
57 size_t dataCapacity = fdp.ConsumeIntegralInRange<size_t>(kNonZeroRangeMin, kRangeMax);
58 cameraMetadata = CameraMetadata(entryCapacity, dataCapacity);
59 }
60 captureRequest->mPhysicalCameraSettings.push_back({id, cameraMetadata});
61 if (fdp.ConsumeBool()) {
62 cameraMetadata.writeToParcel(&parcelCamCaptureReq);
63 }
64 }
65
66 captureRequest->mIsReprocess = fdp.ConsumeBool();
67 if (fdp.ConsumeBool()) {
68 parcelCamCaptureReq.writeInt32(captureRequest->mIsReprocess);
69 }
70
71 captureRequest->mSurfaceConverted = fdp.ConsumeBool();
72 if (fdp.ConsumeBool() && captureRequest->mSurfaceConverted) {
73 // 0-sized array
74 parcelCamCaptureReq.writeInt32(0);
75 }
76
77 if (!captureRequest->mSurfaceConverted) {
78 size_t surfaceListSize = fdp.ConsumeIntegralInRange<size_t>(kSizeMin, kSizeMax);
79 if (fdp.ConsumeBool()) {
80 parcelCamCaptureReq.writeInt32(surfaceListSize);
81 }
82 for (size_t idx = 0; idx < surfaceListSize; ++idx) {
83 sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
84 sp<SurfaceControl> surfaceControl = composerClient->createSurface(
85 static_cast<String8>(fdp.ConsumeRandomLengthString().c_str()) /* name */,
86 fdp.ConsumeIntegral<uint32_t>() /* width */,
87 fdp.ConsumeIntegral<uint32_t>() /* height */,
88 fdp.ConsumeIntegral<int32_t>() /* format */,
89 fdp.ConsumeIntegral<int32_t>() /* flags */);
90 if (surfaceControl) {
91 sp<Surface> surface = surfaceControl->getSurface();
92 captureRequest->mSurfaceList.push_back(surface);
93 if (fdp.ConsumeBool()) {
94 #if WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
95 view::Surface surfaceShim = view::Surface::fromSurface(surface);
96 #else
97 view::Surface surfaceShim;
98 surfaceShim.graphicBufferProducer = surface->getIGraphicBufferProducer();
99 #endif
100 surfaceShim.name = String16((fdp.ConsumeRandomLengthString()).c_str());
101 surfaceShim.writeToParcel(&parcelCamCaptureReq);
102 }
103 surface.clear();
104 }
105 composerClient.clear();
106 surfaceControl.clear();
107 }
108 }
109
110 size_t indexListSize = fdp.ConsumeIntegralInRange<size_t>(kSizeMin, kSizeMax);
111 if (fdp.ConsumeBool()) {
112 parcelCamCaptureReq.writeInt32(indexListSize);
113 }
114
115 for (size_t idx = 0; idx < indexListSize; ++idx) {
116 int32_t streamIdx = fdp.ConsumeIntegral<int32_t>();
117 int32_t surfaceIdx = fdp.ConsumeIntegral<int32_t>();
118 captureRequest->mStreamIdxList.push_back(streamIdx);
119 captureRequest->mSurfaceIdxList.push_back(surfaceIdx);
120 if (fdp.ConsumeBool()) {
121 parcelCamCaptureReq.writeInt32(streamIdx);
122 }
123 if (fdp.ConsumeBool()) {
124 parcelCamCaptureReq.writeInt32(surfaceIdx);
125 }
126 }
127
128 if (fdp.ConsumeBool()) {
129 invokeReadWriteParcelsp<CaptureRequest>(captureRequest);
130 } else {
131 invokeNewReadWriteParcelsp<CaptureRequest>(captureRequest, fdp);
132 }
133 invokeReadWriteNullParcelsp<CaptureRequest>(captureRequest);
134 parcelCamCaptureReq.setDataPosition(0);
135 captureRequest->readFromParcel(&parcelCamCaptureReq);
136 captureRequest.clear();
137 return 0;
138 }
139