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