1 /*
2 * Copyright (c) 2025 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 #include "medialibrary_mtpptpproxy_fuzzer.h"
16
17 #include <cstdint>
18 #include <string>
19 #include <fstream>
20 #include <vector>
21 #include <fuzzer/FuzzedDataProvider.h>
22
23 #include "system_ability_definition.h"
24 #include "iservice_registry.h"
25 #include "userfilemgr_uri.h"
26 #include "payload_data.h"
27 #include "mtp_ptp_const.h"
28 #include "close_session_data.h"
29 #include "media_log.h"
30 #include "medialibrary_errno.h"
31
32 #define private public
33 #include "mtp_ptp_proxy.h"
34 #include "mtp_manager.h"
35 #undef private
36
37 namespace OHOS {
38 using namespace std;
39 using namespace Media;
40
41 static const int32_t MAX_BYTE_VALUE = 256;
42 static const int32_t SEED_SIZE = 1024;
43 const int32_t NUM_BYTES = 1;
44 FuzzedDataProvider *provider = nullptr;
45 const uint32_t OFFSET = 5;
46
47 constexpr int FUZZ_STORAGE_MANAGER_MANAGER_ID = 5003;
48
FuzzMtpOperationContext()49 static MtpOperationContext FuzzMtpOperationContext()
50 {
51 MtpOperationContext context;
52
53 context.operationCode = provider->ConsumeIntegral<uint32_t>();
54 context.transactionID = provider->ConsumeIntegral<uint32_t>();
55 context.devicePropertyCode = provider->ConsumeIntegral<uint32_t>();
56 context.storageID = provider->ConsumeIntegral<uint32_t>();
57 context.format = provider->ConsumeIntegral<uint16_t>();
58 context.parent = provider->ConsumeIntegralInRange<uint32_t>(PTP_IN_MTP_ID - OFFSET, PTP_IN_MTP_ID + OFFSET);
59 context.handle = provider->ConsumeIntegralInRange<uint32_t>(PTP_IN_MTP_ID - OFFSET, PTP_IN_MTP_ID + OFFSET);
60 context.property = provider->ConsumeIntegral<uint32_t>();
61 context.groupCode = provider->ConsumeIntegral<uint32_t>();
62 context.depth = provider->ConsumeIntegral<uint32_t>();
63 context.properStrValue = provider->ConsumeBytesAsString(NUM_BYTES);
64 context.properIntValue = provider->ConsumeIntegral<int64_t>();
65 vector<uint32_t> handles = {provider->ConsumeIntegral<uint32_t>()};
66 context.handles = make_shared<UInt32List>(handles),
67 context.name = provider->ConsumeBytesAsString(NUM_BYTES);
68 context.created = provider->ConsumeBytesAsString(NUM_BYTES);
69 context.modified = provider->ConsumeBytesAsString(NUM_BYTES);
70 context.indata = provider->ConsumeBool();
71 context.storageInfoID = provider->ConsumeIntegral<uint32_t>();
72 context.sessionOpen = provider->ConsumeBool();
73 context.sessionID = provider->ConsumeIntegral<uint32_t>();
74 context.tempSessionID = provider->ConsumeIntegral<uint32_t>();
75 context.eventHandle = provider->ConsumeIntegral<uint32_t>();
76 context.eventProperty = provider->ConsumeIntegral<uint32_t>();
77 return context;
78 }
79
80 // proxy test
ProxyInit(std::shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)81 static void ProxyInit(std::shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
82 {
83 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
84 if (saManager == nullptr) {
85 MEDIA_ERR_LOG("Get system ability mgr failed.");
86 return;
87 }
88 auto remoteObj = saManager->GetSystemAbility(FUZZ_STORAGE_MANAGER_MANAGER_ID);
89 if (remoteObj == nullptr) {
90 MEDIA_ERR_LOG("GetSystemAbility Service Failed.");
91 return;
92 }
93 const sptr<OHOS::IRemoteObject> token = remoteObj;
94 proxy.Init(remoteObj, context);
95 }
96
ProxyGetHandlesTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)97 static void ProxyGetHandlesTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
98 {
99 std::shared_ptr<UInt32List> handles = std::make_shared<UInt32List>();
100 bool isMac = provider->ConsumeBool();
101 proxy.GetHandles(context, handles, isMac);
102 }
103
ProxyGetObjectInfoTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)104 static void ProxyGetObjectInfoTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
105 {
106 std::shared_ptr<ObjectInfo> objectInfo = std::make_shared<ObjectInfo>(0);
107 proxy.GetObjectInfo(context, objectInfo);
108 }
109
ProxyGetObjectPropValueTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)110 static void ProxyGetObjectPropValueTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
111 {
112 uint64_t intVal;
113 uint128_t longVal;
114 std::string strVal;
115 proxy.GetObjectPropValue(context, intVal, longVal, strVal);
116 }
117
ProxySetObjectPropValueTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)118 static void ProxySetObjectPropValueTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
119 {
120 proxy.SetObjectPropValue(context);
121 }
122
ProxyGetObjectPropListTest()123 static void ProxyGetObjectPropListTest()
124 {
125 shared_ptr<MtpOperationContext> context = make_shared<MtpOperationContext>(FuzzMtpOperationContext());
126 auto proxy = MtpPtpProxy::GetInstance();
127 ProxyInit(context, proxy);
128 std::shared_ptr<std::vector<Property>> properties;
129 proxy.GetObjectPropList(context, properties);
130 }
131
ProxyGetReadFdTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)132 static void ProxyGetReadFdTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
133 {
134 int32_t fd;
135 proxy.GetReadFd(context, fd);
136 }
137
ProxyCloseReadFdTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)138 static void ProxyCloseReadFdTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
139 {
140 int32_t fd = provider->ConsumeIntegral<int32_t>();
141 proxy.CloseReadFd(context, fd);
142 }
143
ProxyGetWriteFdTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)144 static void ProxyGetWriteFdTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
145 {
146 int32_t fd = 0;
147 proxy.GetWriteFd(context, fd);
148 }
149
ProxyCloseWriteFdTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)150 static void ProxyCloseWriteFdTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
151 {
152 int32_t fd = provider->ConsumeIntegral<int32_t>();
153 proxy.CloseWriteFd(context, fd);
154 }
155
ProxyGetModifyObjectInfoPathByIdTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)156 static void ProxyGetModifyObjectInfoPathByIdTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
157 {
158 int32_t handle = provider->ConsumeIntegral<int32_t>();
159 std::string path = "";
160 proxy.GetModifyObjectInfoPathById(handle, path);
161 }
162
ProxyGetMtpPathByIdTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)163 static void ProxyGetMtpPathByIdTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
164 {
165 int32_t handle = provider->ConsumeIntegral<int32_t>();
166 std::string path = "";
167 proxy.GetMtpPathById(handle, path);
168 }
169
ProxyGetThumbTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)170 static void ProxyGetThumbTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
171 {
172 std::shared_ptr<UInt8List> outThumb;
173 proxy.GetThumb(context, outThumb);
174 }
175
ProxySendObjectInfoTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)176 static void ProxySendObjectInfoTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
177 {
178 uint32_t storageId = provider->ConsumeIntegral<uint32_t>();
179 uint32_t parent = provider->ConsumeIntegral<uint32_t>();
180 uint32_t handle = provider->ConsumeIntegral<uint32_t>();
181 proxy.SendObjectInfo(context, storageId, parent, handle);
182 }
183
ProxyDeleteObjectTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)184 static void ProxyDeleteObjectTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
185 {
186 proxy.DeleteObject(context);
187 }
188
ProxyMoveObjectTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)189 static void ProxyMoveObjectTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
190 {
191 uint32_t repeatHandle = 0;
192 proxy.MoveObject(context, repeatHandle);
193 }
194
ProxyCopyObjectTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)195 static void ProxyCopyObjectTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
196 {
197 uint32_t oldHandle = provider->ConsumeIntegral<uint32_t>();
198 uint32_t outHandle = 0;
199 proxy.CopyObject(context, outHandle, oldHandle);
200 }
201
ProxyGetMtpStorageIdsTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)202 static void ProxyGetMtpStorageIdsTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
203 {
204 proxy.GetMtpStorageIds();
205 }
206
ProxyGetIdByPathTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)207 static void ProxyGetIdByPathTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
208 {
209 std::string path = provider->ConsumeBytesAsString(NUM_BYTES);
210 uint32_t outId = 0;
211 proxy.GetIdByPath(path, outId);
212 }
213
ProxyGetPathByHandleTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)214 static void ProxyGetPathByHandleTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
215 {
216 uint32_t handle = provider->ConsumeIntegral<uint32_t>();
217 std::string outPath = "";
218 std::string outRealPath = "";
219 proxy.GetPathByHandle(handle, outPath, outRealPath);
220 }
221
ProxyDeleteCanceledObjectTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)222 static void ProxyDeleteCanceledObjectTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
223 {
224 uint32_t handle = provider->ConsumeIntegral<uint32_t>();
225 std::string path = provider->ConsumeBytesAsString(NUM_BYTES);
226 proxy.DeleteCanceledObject(path, handle);
227 }
228
ProxyIsMtpExistObjectTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)229 static void ProxyIsMtpExistObjectTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
230 {
231 proxy.IsMtpExistObject(context);
232 }
233
ProxyMtpTryAddExternalStorageTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)234 static void ProxyMtpTryAddExternalStorageTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
235 {
236 uint32_t storageId = provider->ConsumeIntegral<uint32_t>();
237 std::string fsUuid = provider->ConsumeBytesAsString(NUM_BYTES);
238 proxy.MtpTryAddExternalStorage(fsUuid, storageId);
239 }
240
ProxyMtpTryRemoveExternalStorageTest(shared_ptr<MtpOperationContext> context,MtpPtpProxy & proxy)241 static void ProxyMtpTryRemoveExternalStorageTest(shared_ptr<MtpOperationContext> context, MtpPtpProxy& proxy)
242 {
243 uint32_t storageId = provider->ConsumeIntegral<uint32_t>();
244 std::string fsUuid = provider->ConsumeBytesAsString(NUM_BYTES);
245 proxy.MtpTryRemoveExternalStorage(fsUuid, storageId);
246 }
247
MtpPtpProxyTest()248 static void MtpPtpProxyTest()
249 {
250 shared_ptr<MtpOperationContext> context = make_shared<MtpOperationContext>(FuzzMtpOperationContext());
251 auto proxy = MtpPtpProxy::GetInstance();
252 ProxyInit(context, proxy);
253
254 uint32_t mode = provider->ConsumeIntegralInRange<uint32_t>(0, 2);
255 MtpManager::GetInstance().mtpMode_ = MtpManager::MtpMode(mode);
256
257 ProxyGetHandlesTest(context, proxy);
258 ProxyGetObjectInfoTest(context, proxy);
259 ProxyGetObjectPropValueTest(context, proxy);
260 ProxySetObjectPropValueTest(context, proxy);
261 ProxyGetObjectPropListTest();
262 ProxyGetReadFdTest(context, proxy);
263 ProxyCloseReadFdTest(context, proxy);
264 ProxyGetWriteFdTest(context, proxy);
265 ProxyCloseWriteFdTest(context, proxy);
266 ProxyGetModifyObjectInfoPathByIdTest(context, proxy);
267 ProxyGetMtpPathByIdTest(context, proxy);
268 ProxyGetThumbTest(context, proxy);
269 ProxySendObjectInfoTest(context, proxy);
270 ProxyDeleteObjectTest(context, proxy);
271 ProxyMoveObjectTest(context, proxy);
272 ProxyCopyObjectTest(context, proxy);
273 ProxyGetMtpStorageIdsTest(context, proxy);
274 ProxyGetIdByPathTest(context, proxy);
275 ProxyGetPathByHandleTest(context, proxy);
276 ProxyDeleteCanceledObjectTest(context, proxy);
277 ProxyIsMtpExistObjectTest(context, proxy);
278 ProxyMtpTryAddExternalStorageTest(context, proxy);
279 ProxyMtpTryRemoveExternalStorageTest(context, proxy);
280 }
281
AddSeed()282 static int32_t AddSeed()
283 {
284 char *seedData = new char[OHOS::SEED_SIZE];
285 for (int i = 0; i < OHOS::SEED_SIZE; i++) {
286 seedData[i] = static_cast<char>(i % MAX_BYTE_VALUE);
287 }
288
289 std::string filename = "corpus/seed.txt";
290 std::ofstream file(filename.c_str(), std::ios::binary | std::ios::trunc);
291 if (!file) {
292 MEDIA_ERR_LOG("Cannot open file filename:%{public}s", filename.c_str());
293 delete[] seedData;
294 return Media::E_ERR;
295 }
296 file.write(seedData, OHOS::SEED_SIZE);
297 file.close();
298 delete[] seedData;
299 MEDIA_INFO_LOG("seedData has been successfully written to file filename:%{public}s", filename.c_str());
300 return Media::E_OK;
301 }
302 } // namespace OHOS
303
LLVMFuzzerInitialize(int * argc,char *** argv)304 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
305 {
306 OHOS::AddSeed();
307 return 0;
308 }
309
310 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)311 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
312 {
313 /* Run your code on data */
314 if (data == nullptr) {
315 return 0;
316 }
317
318 FuzzedDataProvider fdp(data, size);
319 OHOS::provider = &fdp;
320
321 OHOS::MtpPtpProxyTest();
322 return 0;
323 }
324