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 "stream_capture_stub_fuzzer.h"
17 #include "foundation/multimedia/camera_framework/common/utils/camera_log.h"
18 #include "hstream_capture.h"
19 #include "iservice_registry.h"
20 #include "message_parcel.h"
21 #include "nativetoken_kit.h"
22 #include "token_setproc.h"
23 #include "accesstoken_kit.h"
24 #include "camera_metadata_info.h"
25 #include "metadata_utils.h"
26 #include "iconsumer_surface.h"
27 #include "camera_service_ipc_interface_code.h"
28 
29 namespace OHOS {
30 namespace CameraStandard {
31 namespace StreamCaptureStubFuzzer {
32 
33 const int32_t LIMITSIZE = 2;
34 const size_t LIMITCOUNT = 4;
35 const int32_t PHOTO_WIDTH = 1280;
36 const int32_t PHOTO_HEIGHT = 960;
37 const int32_t PHOTO_FORMAT = 2000;
38 const uint32_t INVALID_CODE = 9999;
39 const std::u16string FORMMGR_INTERFACE_TOKEN = u"IStreamCapture";
40 const int32_t ITEM_CAP = 10;
41 const int32_t DATA_CAP = 100;
42 
43 bool g_hasPermission = false;
44 HStreamCaptureStub *fuzz = nullptr;
45 
MakeMetadata(uint8_t * rawData,size_t size)46 std::shared_ptr<OHOS::Camera::CameraMetadata> MakeMetadata(uint8_t *rawData, size_t size)
47 {
48     int32_t itemCount = ITEM_CAP;
49     int32_t dataSize = DATA_CAP;
50     int32_t *streams = reinterpret_cast<int32_t *>(rawData);
51     std::shared_ptr<OHOS::Camera::CameraMetadata> ability;
52     ability = std::make_shared<OHOS::Camera::CameraMetadata>(itemCount, dataSize);
53     ability->addEntry(OHOS_ABILITY_STREAM_AVAILABLE_EXTEND_CONFIGURATIONS, streams, size / LIMITCOUNT);
54     int32_t compensationRange[2] = {rawData[0], rawData[1]};
55     ability->addEntry(OHOS_CONTROL_AE_COMPENSATION_RANGE, compensationRange,
56                       sizeof(compensationRange) / sizeof(compensationRange[0]));
57     float focalLength = rawData[0];
58     ability->addEntry(OHOS_ABILITY_FOCAL_LENGTH, &focalLength, 1);
59 
60     int32_t sensorOrientation = rawData[0];
61     ability->addEntry(OHOS_SENSOR_ORIENTATION, &sensorOrientation, 1);
62 
63     int32_t cameraPosition = rawData[0];
64     ability->addEntry(OHOS_ABILITY_CAMERA_POSITION, &cameraPosition, 1);
65 
66     const camera_rational_t aeCompensationStep[] = {{rawData[0], rawData[1]}};
67     ability->addEntry(OHOS_CONTROL_AE_COMPENSATION_STEP, &aeCompensationStep,
68                       sizeof(aeCompensationStep) / sizeof(aeCompensationStep[0]));
69     return ability;
70 }
71 
CheckPermission()72 void CheckPermission()
73 {
74     if (!g_hasPermission) {
75         uint64_t tokenId;
76         const char *perms[0];
77         perms[0] = "ohos.permission.CAMERA";
78         NativeTokenInfoParams infoInstance = { .dcapsNum = 0, .permsNum = 1, .aclsNum = 0, .dcaps = NULL,
79             .perms = perms, .acls = NULL, .processName = "camera_capture", .aplStr = "system_basic",
80         };
81         tokenId = GetAccessTokenId(&infoInstance);
82         SetSelfTokenID(tokenId);
83         OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
84         g_hasPermission = true;
85     }
86 }
87 
Test(uint8_t * rawData,size_t size)88 void Test(uint8_t *rawData, size_t size)
89 {
90     if (rawData == nullptr || size < LIMITSIZE) {
91         return;
92     }
93     CheckPermission();
94 
95     if (fuzz == nullptr) {
96         sptr<IConsumerSurface> photoSurface = IConsumerSurface::Create();
97         CHECK_AND_RETURN_LOG(photoSurface, "StreamCaptureStubFuzzer: Create photoSurface Error");
98         sptr<IBufferProducer> producer = photoSurface->GetProducer();
99         fuzz = new HStreamCapture(producer, PHOTO_FORMAT, PHOTO_WIDTH, PHOTO_HEIGHT);
100     }
101 
102     Test_OnRemoteRequest(rawData, size);
103     Test_HandleCapture(rawData, size);
104     Test_HandleSetThumbnail(rawData, size);
105     Test_HandleSetBufferProducerInfo(rawData, size);
106     Test_HandleEnableDeferredType(rawData, size);
107     Test_HandleSetCallback(rawData, size);
108     fuzz->Release();
109 }
110 
Request(MessageParcel & data,MessageParcel & reply,MessageOption & option,StreamCaptureInterfaceCode scic)111 void Request(MessageParcel &data, MessageParcel &reply, MessageOption &option, StreamCaptureInterfaceCode scic)
112 {
113     uint32_t code = static_cast<uint32_t>(scic);
114     data.RewindRead(0);
115     fuzz->OnRemoteRequest(code, data, reply, option);
116 }
117 
Test_OnRemoteRequest(uint8_t * rawData,size_t size)118 void Test_OnRemoteRequest(uint8_t *rawData, size_t size)
119 {
120     MessageParcel data;
121     data.RewindWrite(0);
122     data.WriteInterfaceToken(FORMMGR_INTERFACE_TOKEN);
123     auto metadata = MakeMetadata(rawData, size);
124     CHECK_AND_RETURN_LOG(OHOS::Camera::MetadataUtils::EncodeCameraMetadata(metadata, data),
125         "StreamCaptureStubFuzzer: EncodeCameraMetadata Error");
126     MessageParcel reply;
127     MessageOption option;
128     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_CAPTURE_START);
129     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_CAPTURE_CANCEL);
130     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_CAPTURE_CONFIRM);
131     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_CAPTURE_SET_CALLBACK);
132     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_CAPTURE_RELEASE);
133     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_SERVICE_SET_THUMBNAIL);
134     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_SERVICE_ENABLE_DEFERREDTYPE);
135     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_GET_DEFERRED_PHOTO);
136     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_GET_DEFERRED_VIDEO);
137     Request(data, reply, option, StreamCaptureInterfaceCode::CAMERA_STREAM_SET_BUFFER_PRODUCER_INFO);
138     uint32_t code = INVALID_CODE;
139     data.RewindRead(0);
140     fuzz->OnRemoteRequest(code, data, reply, option);
141 }
142 
Test_HandleCapture(uint8_t * rawData,size_t size)143 void Test_HandleCapture(uint8_t *rawData, size_t size)
144 {
145     MessageParcel data;
146     // tagCount
147     data.WriteUint32(1);
148     // itemCapacity
149     data.WriteUint32(ITEM_CAP);
150     // dataCapacity
151     data.WriteUint32(DATA_CAP);
152     // item.index
153     data.WriteUint32(0);
154     // item.item
155     data.WriteUint32(1);
156     // item.data_type
157     data.WriteUint32(0);
158     // item.count
159     data.WriteUint32(1);
160     data.WriteInt32(1);
161     data.WriteRawData(rawData, size);
162     data.RewindRead(0);
163     fuzz->HandleCapture(data);
164 }
165 
Test_HandleSetThumbnail(uint8_t * rawData,size_t size)166 void Test_HandleSetThumbnail(uint8_t *rawData, size_t size)
167 {
168     MessageParcel data;
169     sptr<IConsumerSurface> photoSurface = IConsumerSurface::Create();
170     CHECK_AND_RETURN_LOG(photoSurface, "StreamCaptureStubFuzzer: Create photoSurface Error");
171     sptr<IRemoteObject> producer = photoSurface->GetProducer()->AsObject();
172     data.WriteRemoteObject(producer);
173     data.WriteRawData(rawData, size);
174     data.RewindRead(0);
175     fuzz->HandleSetThumbnail(data);
176 }
177 
Test_HandleSetBufferProducerInfo(uint8_t * rawData,size_t size)178 void Test_HandleSetBufferProducerInfo(uint8_t *rawData, size_t size)
179 {
180     MessageParcel data;
181     sptr<IConsumerSurface> photoSurface = IConsumerSurface::Create();
182     CHECK_AND_RETURN_LOG(photoSurface, "StreamCaptureStubFuzzer: Create photoSurface Error");
183     sptr<IRemoteObject> producer = photoSurface->GetProducer()->AsObject();
184     data.WriteRemoteObject(producer);
185     data.WriteRawData(rawData, size);
186     data.RewindRead(0);
187     fuzz->HandleSetBufferProducerInfo(data);
188 }
189 
Test_HandleEnableDeferredType(uint8_t * rawData,size_t size)190 void Test_HandleEnableDeferredType(uint8_t *rawData, size_t size)
191 {
192     MessageParcel data;
193     data.WriteRawData(rawData, size);
194     data.RewindRead(0);
195     fuzz->HandleEnableDeferredType(data);
196 }
197 
Test_HandleSetCallback(uint8_t * rawData,size_t size)198 void Test_HandleSetCallback(uint8_t *rawData, size_t size)
199 {
200     MessageParcel data;
201     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
202     static const int32_t AUDIO_POLICY_SERVICE_ID = 3009;
203     auto object = samgr->GetSystemAbility(AUDIO_POLICY_SERVICE_ID);
204     data.WriteRemoteObject(object);
205     data.WriteRawData(rawData, size);
206     data.RewindRead(0);
207     fuzz->HandleSetCallback(data);
208 }
209 
210 } // namespace StreamCaptureStubFuzzer
211 } // namespace CameraStandard
212 } // namespace OHOS
213 
214 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(uint8_t * data,size_t size)215 extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size)
216 {
217     /* Run your code on data */
218     OHOS::CameraStandard::StreamCaptureStubFuzzer::Test(data, size);
219     return 0;
220 }