1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "metadata_output_fuzzer.h"
17 #include "message_parcel.h"
18 #include "securec.h"
19 #include "camera_log.h"
20 #include "camera_manager.h"
21 #include "camera_device.h"
22 #include "capture_input.h"
23
24 namespace OHOS {
25 namespace CameraStandard {
26 using namespace DeferredProcessing;
27 static constexpr int32_t MAX_CODE_LEN = 512;
28 static constexpr int32_t MIN_SIZE_NUM = 4;
29 static constexpr int32_t streamId = 0;
30 static const uint8_t* RAW_DATA = nullptr;
31 const size_t THRESHOLD = 10;
32 static size_t g_dataSize = 0;
33 static size_t g_pos;
34 static pid_t pid = 0;
35 std::vector<MetadataObjectType> metadataObjectTypes = {
36 MetadataObjectType::BAR_CODE_DETECTION,
37 MetadataObjectType::BASE_FACE_DETECTION,
38 MetadataObjectType::CAT_BODY,
39 MetadataObjectType::CAT_FACE,
40 MetadataObjectType::FACE,
41 };
42 std::vector<MetadataObjectType> typeAdded = {
43 MetadataObjectType::CAT_BODY,
44 MetadataObjectType::CAT_FACE,
45 MetadataObjectType::FACE,
46 };
47 std::vector<MetadataObjectType> supportedType = {
48 MetadataObjectType::CAT_BODY,
49 MetadataObjectType::CAT_FACE,
50 MetadataObjectType::FACE,
51 MetadataObjectType::HUMAN_BODY,
52 };
53
54 std::shared_ptr<MetadataOutput> MetadataOutputFuzzer::fuzz_{nullptr};
55 sptr<CameraManager> cameraManager_ = nullptr;
56
57 /*
58 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
59 * tips: only support basic type
60 */
61 template<class T>
GetData()62 T GetData()
63 {
64 T object {};
65 size_t objectSize = sizeof(object);
66 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
67 return object;
68 }
69 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
70 if (ret != EOK) {
71 return {};
72 }
73 g_pos += objectSize;
74 return object;
75 }
76
77 template<class T>
GetArrLength(T & arr)78 uint32_t GetArrLength(T& arr)
79 {
80 if (arr == nullptr) {
81 MEDIA_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
82 return 0;
83 }
84 return sizeof(arr) / sizeof(arr[0]);
85 }
86
MetadataOutputFuzzTest()87 void MetadataOutputFuzzer::MetadataOutputFuzzTest()
88 {
89 if ((RAW_DATA == nullptr) || (g_dataSize > MAX_CODE_LEN) || (g_dataSize < MIN_SIZE_NUM)) {
90 return;
91 }
92 cameraManager_ = CameraManager::GetInstance();
93 std::vector<sptr<CameraDevice>> cameras = cameraManager_->GetCameraDeviceListFromServer();
94 CHECK_ERROR_RETURN_LOG(cameras.empty(), "MetadataOutputFuzzer: GetCameraDeviceListFromServer Error");
95 sptr<CaptureInput> input = cameraManager_->CreateCameraInput(cameras[0]);
96 CHECK_ERROR_RETURN_LOG(!input, "CreateCameraInput Error");
97 sptr<CaptureOutput> metadata = cameraManager_->CreateMetadataOutput();
98 sptr<CaptureSession> session = cameraManager_->CreateCaptureSession();
99 session->BeginConfig();
100 session->AddInput(input);
101 session->AddOutput(metadata);
102 session->CommitConfig();
103 session->Start();
104 session->innerInputDevice_ = nullptr;
105 sptr<MetadataOutput> metadatOutput = (sptr<MetadataOutput>&)metadata;
106 fuzz_->SetSession(session);
107 fuzz_->CreateStream();
108 fuzz_->GetAppObjectCallback();
109 fuzz_->GetAppStateCallback();
110 fuzz_->GetSupportedMetadataObjectTypes();
111 std::shared_ptr<MetadataObjectCallback> metadataObjectCallback = std::make_shared<AppMetadataCallback>();
112 fuzz_->checkValidType(typeAdded, supportedType);
113 std::vector<MetadataObjectType> typesOfMetadata;
114 typesOfMetadata.push_back(MetadataObjectType::FACE);
115 fuzz_->convert(typesOfMetadata);
116 std::shared_ptr<MetadataObjectCallback> appObjectCallback = std::make_shared<AppMetadataCallback>();
117 fuzz_->appObjectCallback_ = appObjectCallback;
118 sptr<IStreamMetadataCallback> cameraMetadataCallback = new HStreamMetadataCallbackImpl(metadatOutput);
119 fuzz_->cameraMetadataCallback_ = cameraMetadataCallback;
120 fuzz_->SetCallback(appObjectCallback);
121 std::shared_ptr<OHOS::Camera::CameraMetadata> result = session->GetMetadata();
122 std::shared_ptr<HStreamMetadataCallbackImpl> hstreamMetadataCallbackImpl =
123 std::make_shared<HStreamMetadataCallbackImpl>(metadatOutput);
124 hstreamMetadataCallbackImpl->OnMetadataResult(streamId, result);
125 fuzz_->Release();
126 fuzz_->appStateCallback_ = nullptr;
127 fuzz_->CameraServerDied(pid);
128 }
129
MetadataOutputFuzzTest1()130 void MetadataOutputFuzzer::MetadataOutputFuzzTest1()
131 {
132 if ((RAW_DATA == nullptr) || (g_dataSize > MAX_CODE_LEN) || (g_dataSize < MIN_SIZE_NUM)) {
133 return;
134 }
135 std::shared_ptr<MetadataObjectFactory> factory = std::make_shared<MetadataObjectFactory>();
136 factory->ResetParameters();
137 MetadataObjectType type = MetadataObjectType::HUMAN_BODY;
138 sptr<MetadataObject> ret = factory->createMetadataObject(type);
139 IDeferredPhotoProcessingSessionCallbackFuzz callback;
140 auto object = callback.AsObject();
141 sptr<IStreamMetadata> streamMetadata = iface_cast<IStreamMetadata>(object);
142 sptr<IConsumerSurface> surface = IConsumerSurface::Create();
143 sptr<MetadataObjectFactory> factoryPtr = MetadataObjectFactory::GetInstance();
144 sptr<MetadataObjectFactory> factoryPtr_2 = MetadataObjectFactory::GetInstance();
145 std::shared_ptr<OHOS::Camera::CameraMetadata> result = nullptr;
146 std::vector<sptr<MetadataObject>> metaObjects = {};
147 bool isNeedMirror = GetData<bool>();
148 bool isNeedFlip = GetData<bool>();
149 fuzz_->ProcessMetadata(streamId, result, metaObjects, isNeedMirror, isNeedFlip);
150 camera_metadata_item_t metadataItem;
151 fuzz_->reportFaceResults_ = GetData<bool>();
152 fuzz_->GenerateObjects(metadataItem, type, metaObjects, isNeedMirror, isNeedFlip);
153 fuzz_->ProcessRectBox(GetData<int32_t>(), GetData<int32_t>(), GetData<int32_t>(),
154 GetData<int32_t>(), isNeedMirror, isNeedFlip);
155 int32_t index = GetData<int32_t>();
156 fuzz_->ProcessExternInfo(factoryPtr, metadataItem, index, type, isNeedMirror, isNeedFlip);
157 fuzz_->GetSurface();
158 fuzz_->surface_ = nullptr;
159 fuzz_->ReleaseSurface();
160 fuzz_->SetCapturingMetadataObjectTypes(metadataObjectTypes);
161 fuzz_->AddMetadataObjectTypes(metadataObjectTypes);
162 fuzz_->RemoveMetadataObjectTypes(metadataObjectTypes);
163 }
164
Test()165 void Test()
166 {
167 auto metadataOutput = std::make_unique<MetadataOutputFuzzer>();
168 if (metadataOutput == nullptr) {
169 MEDIA_INFO_LOG("metadataOutput is null");
170 return;
171 }
172 IDeferredPhotoProcessingSessionCallbackFuzz callback;
173 auto object = callback.AsObject();
174 sptr<IStreamMetadata> streamMetadata = iface_cast<IStreamMetadata>(object);
175 sptr<IConsumerSurface> surface = IConsumerSurface::Create();
176 MetadataOutputFuzzer::fuzz_ = std::make_shared<MetadataOutput>(surface, streamMetadata);
177 CHECK_ERROR_RETURN_LOG(!MetadataOutputFuzzer::fuzz_, "Create fuzz_ Error");
178 metadataOutput->MetadataOutputFuzzTest();
179 metadataOutput->MetadataOutputFuzzTest1();
180 }
181
182 typedef void (*TestFuncs[1])();
183
184 TestFuncs g_testFuncs = {
185 Test,
186 };
187
FuzzTest(const uint8_t * rawData,size_t size)188 bool FuzzTest(const uint8_t* rawData, size_t size)
189 {
190 // initialize data
191 RAW_DATA = rawData;
192 g_dataSize = size;
193 g_pos = 0;
194
195 uint32_t code = GetData<uint32_t>();
196 uint32_t len = GetArrLength(g_testFuncs);
197 if (len > 0) {
198 g_testFuncs[code % len]();
199 } else {
200 MEDIA_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
201 }
202
203 return true;
204 }
205 } // namespace CameraStandard
206 } // namespace OHOS
207
208 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(uint8_t * data,size_t size)209 extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size)
210 {
211 if (size < OHOS::CameraStandard::THRESHOLD) {
212 return 0;
213 }
214
215 OHOS::CameraStandard::FuzzTest(data, size);
216 return 0;
217 }