1 /*
2 * Copyright (c) 2023 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 "camera_device_fuzzer.h"
17 #include "camera_log.h"
18 #include "camera_xcollie.h"
19 #include "camera_dynamic_loader.h"
20 #include "input/camera_manager.h"
21 #include "metadata_utils.h"
22 #include "ipc_skeleton.h"
23 #include "accesstoken_kit.h"
24 #include "nativetoken_kit.h"
25 #include "token_setproc.h"
26 #include <fuzzer/FuzzedDataProvider.h>
27 #include "hcamera_device.h"
28 using namespace std;
29
30 const uint8_t TEST_NUM = 6;
31 const uint8_t TEST_INDEX_ONE = 1;
32 const uint8_t TEST_INDEX_TWO = 2;
33 const uint8_t TEST_INDEX_THREE = 3;
34 const uint8_t TEST_INDEX_FOUR = 4;
35
36 namespace OHOS {
37 namespace CameraStandard {
38 const std::u16string FORMMGR_INTERFACE_TOKEN = u"ICameraDeviceService";
39 const size_t LIMITCOUNT = 4;
40 const int32_t NUM_TWO = 2;
41 const int32_t NUM_10 = 10;
42 const int32_t NUM_100 = 100;
43 bool g_isCameraDevicePermission = false;
44 sptr<HCameraDevice> fuzzCameraDevice = nullptr;
45
CameraDeviceFuzzTestGetPermission()46 void CameraDeviceFuzzTestGetPermission()
47 {
48 if (!g_isCameraDevicePermission) {
49 uint64_t tokenId;
50 const char *perms[0];
51 perms[0] = "ohos.permission.CAMERA";
52 NativeTokenInfoParams infoInstance = { .dcapsNum = 0, .permsNum = 1, .aclsNum = 0, .dcaps = NULL,
53 .perms = perms, .acls = NULL, .processName = "camera_capture", .aplStr = "system_basic",
54 };
55 tokenId = GetAccessTokenId(&infoInstance);
56 SetSelfTokenID(tokenId);
57 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
58 g_isCameraDevicePermission = true;
59 }
60 }
61
PrepareHCameraDevice()62 void PrepareHCameraDevice()
63 {
64 if (fuzzCameraDevice == nullptr) {
65 sptr<HCameraHostManager> cameraHostManager = new HCameraHostManager(nullptr);
66 std::vector<std::string> cameraIds;
67 cameraHostManager->GetCameras(cameraIds);
68 CHECK_ERROR_RETURN_LOG(cameraIds.empty(), "Fuzz:PrepareHCameraDevice: GetCameras returns empty");
69 string cameraID = cameraIds[0];
70 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
71 MEDIA_INFO_LOG("Fuzz:PrepareHCameraDevice: callingTokenId = %{public}d", callingTokenId);
72 string permissionName = OHOS_PERMISSION_CAMERA;
73 int32_t ret = CheckPermission(permissionName, callingTokenId);
74 CHECK_ERROR_RETURN_LOG(ret != CAMERA_OK, "Fuzz:PrepareHCameraDevice: CheckPermission Failed");
75 fuzzCameraDevice = new HCameraDevice(cameraHostManager, cameraID, callingTokenId);
76 MEDIA_INFO_LOG("Fuzz:PrepareHCameraDevice: Success");
77 }
78 }
79
CameraDeviceFuzzTest(uint8_t * rawData,size_t size)80 void CameraDeviceFuzzTest(uint8_t *rawData, size_t size)
81 {
82 if (rawData == nullptr || size < NUM_TWO) {
83 return;
84 }
85 CameraDeviceFuzzTestGetPermission();
86 FuzzedDataProvider fdp(rawData, size);
87
88 int32_t itemCount = NUM_10;
89 int32_t dataSize = NUM_100;
90 int32_t *streams = reinterpret_cast<int32_t *>(rawData);
91 std::shared_ptr<OHOS::Camera::CameraMetadata> ability;
92 ability = std::make_shared<OHOS::Camera::CameraMetadata>(itemCount, dataSize);
93 ability->addEntry(OHOS_ABILITY_STREAM_AVAILABLE_EXTEND_CONFIGURATIONS, streams, size / LIMITCOUNT);
94 int32_t compensationRange[2] = {rawData[0], rawData[1]};
95 ability->addEntry(OHOS_CONTROL_AE_COMPENSATION_RANGE, compensationRange,
96 sizeof(compensationRange) / sizeof(compensationRange[0]));
97 float focalLength = fdp.ConsumeFloatingPoint<float>();
98 ability->addEntry(OHOS_ABILITY_FOCAL_LENGTH, &focalLength, 1);
99
100 int32_t sensorOrientation = fdp.ConsumeIntegral<int32_t>();
101 ability->addEntry(OHOS_SENSOR_ORIENTATION, &sensorOrientation, 1);
102
103 int32_t cameraPosition = fdp.ConsumeIntegral<int32_t>();
104 ability->addEntry(OHOS_ABILITY_CAMERA_POSITION, &cameraPosition, 1);
105
106 const camera_rational_t aeCompensationStep[] = {{rawData[0], rawData[1]}};
107 ability->addEntry(OHOS_CONTROL_AE_COMPENSATION_STEP, &aeCompensationStep,
108 sizeof(aeCompensationStep) / sizeof(aeCompensationStep[0]));
109
110 MessageParcel data;
111 data.WriteInterfaceToken(FORMMGR_INTERFACE_TOKEN);
112 CHECK_ERROR_RETURN_LOG(!(OHOS::Camera::MetadataUtils::EncodeCameraMetadata(ability, data)),
113 "CameraDeviceFuzzer: EncodeCameraMetadata Error");
114 data.RewindRead(0);
115 MessageParcel reply;
116 MessageOption option;
117 PrepareHCameraDevice();
118 if (fuzzCameraDevice) {
119 uint32_t code = 4;
120 fuzzCameraDevice->OnRemoteRequest(code, data, reply, option);
121 }
122 }
123
CameraDeviceFuzzTestUpdateSetting(uint8_t * rawData,size_t size)124 void CameraDeviceFuzzTestUpdateSetting(uint8_t *rawData, size_t size)
125 {
126 if (rawData == nullptr || size < NUM_TWO) {
127 return;
128 }
129 CameraDeviceFuzzTestGetPermission();
130 FuzzedDataProvider fdp(rawData, size);
131 int32_t itemCount = NUM_10;
132 int32_t dataSize = NUM_100;
133 int32_t *streams = reinterpret_cast<int32_t *>(rawData);
134 auto ability = std::make_shared<OHOS::Camera::CameraMetadata>(itemCount, dataSize);
135 ability->addEntry(OHOS_ABILITY_STREAM_AVAILABLE_EXTEND_CONFIGURATIONS, streams, size / LIMITCOUNT);
136 int32_t compensationRange[2] = {rawData[0], rawData[1]};
137 ability->addEntry(OHOS_CONTROL_AE_COMPENSATION_RANGE, compensationRange,
138 sizeof(compensationRange) / sizeof(compensationRange[0]));
139 float focalLength = fdp.ConsumeFloatingPoint<float>();
140 ability->addEntry(OHOS_ABILITY_FOCAL_LENGTH, &focalLength, 1);
141
142 int32_t sensorOrientation = fdp.ConsumeIntegral<int32_t>();
143 ability->addEntry(OHOS_SENSOR_ORIENTATION, &sensorOrientation, 1);
144
145 int32_t cameraPosition = fdp.ConsumeIntegral<int32_t>();
146 ability->addEntry(OHOS_ABILITY_CAMERA_POSITION, &cameraPosition, 1);
147
148 const camera_rational_t aeCompensationStep[] = {{rawData[0], rawData[1]}};
149 ability->addEntry(OHOS_CONTROL_AE_COMPENSATION_STEP, &aeCompensationStep,
150 sizeof(aeCompensationStep) / sizeof(aeCompensationStep[0]));
151 if (fuzzCameraDevice) {
152 fuzzCameraDevice->UpdateSettingOnce(ability);
153 fuzzCameraDevice->UpdateSetting(ability);
154 auto out = std::make_shared<OHOS::Camera::CameraMetadata>(itemCount, dataSize);
155 fuzzCameraDevice->GetStatus(ability, out);
156 MessageParcel data;
157 data.WriteRawData(rawData, size);
158 vector<uint8_t> result;
159 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(ability, result);
160 fuzzCameraDevice->OnResult(data.ReadUint64(), result);
161 auto type = OHOS::HDI::Camera::V1_0::ErrorType::REQUEST_TIMEOUT;
162 fuzzCameraDevice->OnError(type, data.ReadInt32());
163 }
164 }
165
CameraDeviceFuzzTest2Case1(uint8_t * rawData,size_t size)166 void CameraDeviceFuzzTest2Case1(uint8_t *rawData, size_t size)
167 {
168 MessageParcel data;
169 data.WriteRawData(rawData, size);
170 if (fuzzCameraDevice) {
171 fuzzCameraDevice->GetStreamOperatorCallback();
172 fuzzCameraDevice->GetCallerToken();
173 fuzzCameraDevice->GetDeviceAbility();
174 fuzzCameraDevice->GetCameraType();
175 fuzzCameraDevice->GetCameraId();
176 }
177 }
178
CameraDeviceFuzzTest2Case2(uint8_t * rawData,size_t size)179 void CameraDeviceFuzzTest2Case2(uint8_t *rawData, size_t size)
180 {
181 // 运行会出错
182 MessageParcel data;
183 data.WriteRawData(rawData, size);
184 sptr<ICameraDeviceServiceCallback> callback(new ICameraDeviceServiceCallbackMock());
185 fuzzCameraDevice->SetCallback(callback);
186 wptr<IStreamOperatorCallback> opCallback(new IStreamOperatorCallbackMock());
187 fuzzCameraDevice->SetStreamOperatorCallback(opCallback);
188 vector<int32_t> results{data.ReadInt32()};
189 fuzzCameraDevice->EnableResult(results);
190 fuzzCameraDevice->DisableResult(results);
191 fuzzCameraDevice->CloneCachedSettings();
192 fuzzCameraDevice->DispatchDefaultSettingToHdi();
193 fuzzCameraDevice->Release();
194 fuzzCameraDevice->Close();
195 uint64_t secureSeqId;
196 fuzzCameraDevice->GetSecureCameraSeq(&secureSeqId);
197 fuzzCameraDevice->OpenSecureCamera(&secureSeqId);
198 }
199
CameraDeviceFuzzTest2(uint8_t * rawData,size_t size)200 void CameraDeviceFuzzTest2(uint8_t *rawData, size_t size)
201 {
202 if (rawData == nullptr || size < NUM_TWO) {
203 return;
204 }
205 MessageParcel data;
206 data.WriteRawData(rawData, size);
207 if (fuzzCameraDevice) {
208 fuzzCameraDevice->OperatePermissionCheck(data.ReadUint32());
209 fuzzCameraDevice->Open();
210 fuzzCameraDevice->CheckMovingPhotoSupported(data.ReadInt32());
211 fuzzCameraDevice->NotifyCameraStatus(data.ReadInt32());
212 fuzzCameraDevice->RemoveResourceWhenHostDied();
213 fuzzCameraDevice->NotifyCameraSessionStatus(data.ReadBool());
214 CameraDeviceFuzzTest2Case1(rawData, size);
215 fuzzCameraDevice->ResetDeviceSettings();
216 fuzzCameraDevice->SetDeviceMuteMode(data.ReadBool());
217 fuzzCameraDevice->IsOpenedCameraDevice();
218 fuzzCameraDevice->CloseDevice();
219 }
220 }
221
GetPermission()222 void GetPermission()
223 {
224 uint64_t tokenId;
225 const char* perms[2];
226 perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
227 perms[1] = "ohos.permission.CAMERA";
228 NativeTokenInfoParams infoInstance = {
229 .dcapsNum = 0,
230 .permsNum = 2,
231 .aclsNum = 0,
232 .dcaps = NULL,
233 .perms = perms,
234 .acls = NULL,
235 .processName = "native_camera_tdd",
236 .aplStr = "system_basic",
237 };
238 tokenId = GetAccessTokenId(&infoInstance);
239 SetSelfTokenID(tokenId);
240 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
241 }
242
Test3(uint8_t * rawData,size_t size)243 void Test3(uint8_t *rawData, size_t size)
244 {
245 if (rawData == nullptr || size < NUM_TWO) {
246 return;
247 }
248 GetPermission();
249 auto manager = CameraManager::GetInstance();
250 auto cameras = manager->GetSupportedCameras();
251 CHECK_ERROR_RETURN_LOG(cameras.size() < NUM_TWO, "PhotoOutputFuzzer: GetSupportedCameras Error");
252 MessageParcel data;
253 data.WriteRawData(rawData, size);
254 sptr<CameraDevice> camera = cameras[data.ReadUint32() % cameras.size()];
255 camera->GetID();
256 camera->GetMetadata();
257 camera->ResetMetadata();
258 camera->GetCameraAbility();
259 camera->GetPosition();
260 camera->GetCameraType();
261 camera->GetConnectionType();
262 camera->GetCameraFoldScreenType();
263 camera->GetHostName();
264 camera->GetDeviceType();
265 camera->GetNetWorkId();
266 camera->GetCameraOrientation();
267 camera->GetExposureBiasRange();
268 camera->GetModuleType();
269 camera->GetUsedAsPosition();
270 CameraFormat format = static_cast<CameraFormat>(data.ReadInt32());
271 auto capability = manager->GetSupportedOutputCapability(camera);
272 CHECK_ERROR_RETURN_LOG(!capability, "PhotoOutputFuzzer: GetSupportedOutputCapability Error");
273 vector<Profile> profiles = capability->GetPhotoProfiles();
274 camera->GetMaxSizeProfile(profiles, data.ReadFloat(), format);
275 auto profiles2 = capability->GetVideoProfiles();
276 camera->GetMaxSizeProfile(profiles2, data.ReadFloat(), format);
277 camera->SetProfile(capability);
278 auto modeName = data.ReadInt32();
279 camera->SetProfile(capability, modeName);
280 camera->SetCameraDeviceUsedAsPosition(CameraPosition::CAMERA_POSITION_FRONT);
281 camera->GetSupportedFoldStatus();
282 auto randomNum = data.ReadUint32();
283 std::vector<std::string> testStrings = {"cameraid1", "cameraid2"};
284 std::string cameraID(testStrings[randomNum % testStrings.size()]);
285 std::shared_ptr<OHOS::Camera::CameraMetadata> metadata =
286 std::make_shared<OHOS::Camera::CameraMetadata>(NUM_10, NUM_100);
287 std::shared_ptr<CameraDevice> cameraDevice =
288 std::make_shared<CameraDevice>(cameraID, metadata);
289 }
290
TestXCollie(uint8_t * rawData,size_t size)291 void TestXCollie(uint8_t *rawData, size_t size)
292 {
293 CHECK_ERROR_RETURN(rawData == nullptr || size < NUM_TWO);
294 MessageParcel data;
295 data.WriteRawData(rawData, size);
296 string tag = data.ReadString();
297 uint32_t flag = data.ReadInt32();
298 uint32_t timeoutSeconds = data.ReadUint32();
299 auto func = [](void*) {};
300 #ifndef HICOLLIE_ENABLE
301 #define HICOLLIE_ENABLE
302 #endif
303 {
304 CameraXCollie collie(tag, flag, timeoutSeconds, func, nullptr);
305 collie.CancelCameraXCollie();
306 }
307 #undef HICOLLIE_ENABLE
308 {
309 CameraXCollie collie(tag, flag, timeoutSeconds, func, nullptr);
310 collie.CancelCameraXCollie();
311 }
312 }
313
TestDynamicLoader(uint8_t * rawData,size_t size)314 void TestDynamicLoader(uint8_t *rawData, size_t size)
315 {
316 CHECK_ERROR_RETURN(rawData == nullptr || size < NUM_TWO);
317 MessageParcel data;
318 data.WriteRawData(rawData, size);
319
320 string libName = data.ReadString();
321 CameraDynamicLoader::GetDynamiclib(libName);
322 CameraDynamicLoader::LoadDynamiclibAsync(libName);
323 CameraDynamicLoader::FreeDynamiclib(libName);
324 }
325
TestCameraDeviceServiceCallback(uint8_t * rawData,size_t size)326 void TestCameraDeviceServiceCallback(uint8_t *rawData, size_t size)
327 {
328 CHECK_ERROR_RETURN(rawData == nullptr || size < NUM_TWO);
329 MessageParcel data;
330 data.WriteRawData(rawData, size);
331 auto meta = make_shared<OHOS::Camera::CameraMetadata>(10, 100);
332 int val = 1;
333 AddOrUpdateMetadata(meta, OHOS_STATUS_CAMERA_OCCLUSION_DETECTION, &val, 1);
334
335 CameraDeviceServiceCallback callback;
336 callback.OnError(data.ReadInt32(), data.ReadInt32());
337 callback.OnResult(data.ReadUint64(), meta);
338
339 auto manager = CameraManager::GetInstance();
340 auto cameras = manager->GetSupportedCameras();
341 auto input = manager->CreateCameraInput(cameras[0]);
342 class ErrorCallbackMock : public ErrorCallback {
343 public:
344 void OnError(const int32_t errorType, const int32_t errorMsg) const override {}
345 };
346 input->SetErrorCallback(make_shared<ErrorCallbackMock>());
347 class ResultCallbackMock : public ResultCallback {
348 public:
349 void OnResult(const uint64_t timestamp,
350 const std::shared_ptr<OHOS::Camera::CameraMetadata> &result) const override {}
351 };
352 input->SetResultCallback(make_shared<ResultCallbackMock>());
353 class CameraOcclusionDetectCallbackMock : public CameraOcclusionDetectCallback {
354 public:
355 void OnCameraOcclusionDetected(const uint8_t isCameraOcclusion,
356 const uint8_t isCameraLensDirty) const override {}
357 };
358 input->SetOcclusionDetectCallback(make_shared<CameraOcclusionDetectCallbackMock>());
359 CameraDeviceServiceCallback callback2(input);
360 callback2.OnError(data.ReadInt32(), data.ReadInt32());
361 callback2.OnResult(data.ReadUint64(), meta);
362 input->GetCameraDeviceInfo().clear();
363 callback2.OnError(data.ReadInt32(), data.ReadInt32());
364 callback2.OnResult(data.ReadUint64(), meta);
365 input->Release();
366 }
367 } // namespace CameraStandard
368 } // namespace OHOS
369
370 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(uint8_t * data,size_t size)371 extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size)
372 {
373 /* Run your code on data */
374 uint8_t firstByte = *data;
375 firstByte = firstByte % TEST_NUM;
376 switch (firstByte) {
377 case 0:
378 OHOS::CameraStandard::CameraDeviceFuzzTest(data, size);
379 break;
380 case TEST_INDEX_ONE:
381 OHOS::CameraStandard::CameraDeviceFuzzTestUpdateSetting(data, size);
382 break;
383 case TEST_INDEX_TWO:
384 OHOS::CameraStandard::CameraDeviceFuzzTest2(data, size);
385 break;
386 case TEST_INDEX_THREE:
387 OHOS::CameraStandard::Test3(data, size);
388 break;
389 case TEST_INDEX_FOUR:
390 OHOS::CameraStandard::TestXCollie(data, size);
391 break;
392 default:
393 OHOS::CameraStandard::TestDynamicLoader(data, size);
394 break;
395 }
396 return 0;
397 }