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 <CameraParameters.h>
18 #include <CameraParameters2.h>
19 #include <camera/StringUtils.h>
20 #include <fcntl.h>
21 #include <fuzzer/FuzzedDataProvider.h>
22 #include <utils/String16.h>
23 #include <camera/StringUtils.h>
24
25 #include <functional>
26
27 using namespace std;
28 using namespace android;
29
30 constexpr int8_t kMaxBytes = 20;
31
32 string kValidFormats[] = {
33 CameraParameters::PIXEL_FORMAT_YUV422SP, CameraParameters::PIXEL_FORMAT_YUV420SP,
34 CameraParameters::PIXEL_FORMAT_YUV422I, CameraParameters::PIXEL_FORMAT_YUV420P,
35 CameraParameters::PIXEL_FORMAT_RGB565, CameraParameters::PIXEL_FORMAT_RGBA8888,
36 CameraParameters::PIXEL_FORMAT_JPEG, CameraParameters::PIXEL_FORMAT_BAYER_RGGB,
37 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE};
38
39 class CameraParametersFuzzer {
40 public:
41 void process(const uint8_t* data, size_t size);
42
43 private:
44 void invokeCameraParameters();
45 template <class type>
46 void initCameraParameters(unique_ptr<type>& obj);
47 template <class type>
48 void callCameraParametersAPIs(unique_ptr<type>& obj);
49 unique_ptr<CameraParameters> mCameraParameters;
50 unique_ptr<CameraParameters2> mCameraParameters2;
51 FuzzedDataProvider* mFDP = nullptr;
52 };
53
54 template <class type>
initCameraParameters(unique_ptr<type> & obj)55 void CameraParametersFuzzer::initCameraParameters(unique_ptr<type>& obj) {
56 if (mFDP->ConsumeBool()) {
57 obj = make_unique<type>();
58 } else {
59 string params;
60 if (mFDP->ConsumeBool()) {
61 int32_t width = mFDP->ConsumeIntegral<int32_t>();
62 int32_t height = mFDP->ConsumeIntegral<int32_t>();
63 int32_t minFps = mFDP->ConsumeIntegral<int32_t>();
64 int32_t maxFps = mFDP->ConsumeIntegral<int32_t>();
65 params = mFDP->ConsumeBool() ? mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()
66 : CameraParameters::KEY_SUPPORTED_VIDEO_SIZES;
67 params += '=' + to_string(width) + 'x' + to_string(height) + ';';
68 if (mFDP->ConsumeBool()) {
69 params += mFDP->ConsumeBool() ? mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()
70 : CameraParameters::KEY_PREVIEW_FPS_RANGE;
71 params += '=' + to_string(minFps) + ',' + to_string(maxFps) + ';';
72 }
73 if (mFDP->ConsumeBool()) {
74 params += mFDP->ConsumeBool() ? mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()
75 : CameraParameters::KEY_SUPPORTED_PICTURE_SIZES;
76 params += '=' + to_string(width) + 'x' + to_string(height) + ';';
77 }
78 if (mFDP->ConsumeBool()) {
79 params += mFDP->ConsumeBool() ? mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()
80 : CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS;
81 params += '=' +
82 (mFDP->ConsumeBool() ? mFDP->ConsumeRandomLengthString(kMaxBytes).c_str()
83 : mFDP->PickValueInArray(kValidFormats)) + ';';
84 }
85 } else {
86 params = mFDP->ConsumeRandomLengthString(kMaxBytes);
87 }
88 obj = make_unique<type>(toString8(params));
89 }
90 }
91
92 template <class type>
callCameraParametersAPIs(unique_ptr<type> & obj)93 void CameraParametersFuzzer::callCameraParametersAPIs(unique_ptr<type>& obj) {
94 Vector<Size> supportedVideoSizes;
95 while (mFDP->remaining_bytes()) {
96 auto callCameraUtilsAPIs = mFDP->PickValueInArray<const std::function<void()>>({
97 [&]() {
98 Vector<Size> supportedPreviewSizes;
99 obj->getSupportedPreviewSizes(supportedPreviewSizes);
100 },
101 [&]() {
102 int32_t previewWidth = mFDP->ConsumeIntegral<int32_t>();
103 int32_t previewHeight = mFDP->ConsumeIntegral<int32_t>();
104 obj->setPreviewSize(previewWidth, previewHeight);
105 },
106 [&]() {
107 int32_t previewWidth, previewHeight;
108 obj->getPreviewSize(&previewWidth, &previewHeight);
109 },
110 [&]() { obj->getSupportedVideoSizes(supportedVideoSizes); },
111 [&]() {
112 int32_t videoWidth, videoHeight;
113 if (supportedVideoSizes.size()) {
114 int32_t idx = mFDP->ConsumeIntegralInRange<int32_t>(
115 0, supportedVideoSizes.size() - 1);
116 videoWidth = mFDP->ConsumeBool() ? supportedVideoSizes[idx].width
117 : mFDP->ConsumeIntegral<int32_t>();
118 videoHeight = mFDP->ConsumeBool() ? supportedVideoSizes[idx].height
119 : mFDP->ConsumeIntegral<int32_t>();
120 obj->setVideoSize(videoWidth, videoHeight);
121 }
122 },
123 [&]() {
124 int32_t videoWidth, videoHeight;
125 obj->getVideoSize(&videoWidth, &videoHeight);
126 },
127 [&]() {
128 int32_t preferredVideoWidth, preferredVideoHeight;
129 obj->getPreferredPreviewSizeForVideo(&preferredVideoWidth,
130 &preferredVideoHeight);
131 },
132 [&]() {
133 int32_t fps = mFDP->ConsumeIntegral<int32_t>();
134 obj->setPreviewFrameRate(fps);
135 },
136 [&]() { obj->getPreviewFrameRate(); },
137 [&]() {
138 string previewFormat = mFDP->ConsumeBool()
139 ? mFDP->PickValueInArray(kValidFormats)
140 : mFDP->ConsumeRandomLengthString(kMaxBytes);
141 obj->setPreviewFormat(previewFormat.c_str());
142 },
143 [&]() {
144 int32_t pictureWidth = mFDP->ConsumeIntegral<int32_t>();
145 int32_t pictureHeight = mFDP->ConsumeIntegral<int32_t>();
146 obj->setPictureSize(pictureWidth, pictureHeight);
147 },
148 [&]() {
149 int32_t pictureWidth, pictureHeight;
150 obj->getPictureSize(&pictureWidth, &pictureHeight);
151 },
152 [&]() {
153 Vector<Size> supportedPictureSizes;
154 obj->getSupportedPictureSizes(supportedPictureSizes);
155 },
156 [&]() {
157 string pictureFormat = mFDP->ConsumeBool()
158 ? mFDP->PickValueInArray(kValidFormats)
159 : mFDP->ConsumeRandomLengthString(kMaxBytes);
160 obj->setPictureFormat(pictureFormat.c_str());
161 },
162 [&]() { obj->getPictureFormat(); },
163 [&]() {
164 if (mFDP->ConsumeBool()) {
165 obj->dump();
166 } else {
167 int32_t fd = open("/dev/null", O_CLOEXEC | O_RDWR | O_CREAT);
168 Vector<String16> args = {};
169 obj->dump(fd, args);
170 close(fd);
171 }
172 },
173 [&]() { obj->flatten(); },
174 [&]() {
175 string key = mFDP->ConsumeRandomLengthString(kMaxBytes);
176 float value = mFDP->ConsumeFloatingPoint<float>();
177 obj->setFloat(key.c_str(), value);
178 },
179 [&]() {
180 string key = mFDP->ConsumeRandomLengthString(kMaxBytes);
181 obj->getFloat(key.c_str());
182 },
183 [&]() { obj->getPreviewFormat(); },
184 [&]() {
185 string key = mFDP->ConsumeRandomLengthString(kMaxBytes);
186 obj->remove(key.c_str());
187 },
188 [&]() {
189 if (std::is_same_v<type, CameraParameters>) {
190 string format = mFDP->ConsumeBool()
191 ? mFDP->ConsumeRandomLengthString(kMaxBytes)
192 : mFDP->PickValueInArray(kValidFormats);
193 mCameraParameters->previewFormatToEnum(format.c_str());
194 }
195 },
196 [&]() {
197 if (std::is_same_v<type, CameraParameters>) {
198 mCameraParameters->isEmpty();
199 }
200 },
201 [&]() {
202 if (std::is_same_v<type, CameraParameters>) {
203 Vector<int32_t> formats;
204 mCameraParameters->getSupportedPreviewFormats(formats);
205 }
206 },
207 [&]() {
208 if (std::is_same_v<type, CameraParameters2>) {
209 string key1 = mFDP->ConsumeRandomLengthString(kMaxBytes);
210 string key2 = mFDP->ConsumeRandomLengthString(kMaxBytes);
211 int32_t order;
212 mCameraParameters2->compareSetOrder(key1.c_str(), key2.c_str(), &order);
213 }
214 },
215 [&]() {
216 if (std::is_same_v<type, CameraParameters2>) {
217 int32_t minFps = mFDP->ConsumeIntegral<int32_t>();
218 int32_t maxFps = mFDP->ConsumeIntegral<int32_t>();
219 mCameraParameters2->setPreviewFpsRange(minFps, maxFps);
220 }
221 },
222 });
223 callCameraUtilsAPIs();
224 }
225 }
226
invokeCameraParameters()227 void CameraParametersFuzzer::invokeCameraParameters() {
228 if (mFDP->ConsumeBool()) {
229 initCameraParameters<CameraParameters>(mCameraParameters);
230 callCameraParametersAPIs(mCameraParameters);
231 } else {
232 initCameraParameters<CameraParameters2>(mCameraParameters2);
233 callCameraParametersAPIs(mCameraParameters2);
234 }
235 }
236
process(const uint8_t * data,size_t size)237 void CameraParametersFuzzer::process(const uint8_t* data, size_t size) {
238 mFDP = new FuzzedDataProvider(data, size);
239 invokeCameraParameters();
240 delete mFDP;
241 }
242
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)243 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
244 CameraParametersFuzzer cameraParametersFuzzer;
245 cameraParametersFuzzer.process(data, size);
246 return 0;
247 }
248