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