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 #include "fileaccessextstub_fuzzer.h"
16
17 #include <cstring>
18 #include <memory>
19
20 #include "accesstoken_kit.h"
21 #include "extension_base.h"
22 #include "extension_context.h"
23 #include "file_access_ext_stub.h"
24 #include "file_access_ext_stub_impl.h"
25 #include "fileaccessextabilitymock.h"
26 #include "message_parcel.h"
27
28 namespace OHOS {
29 using namespace std;
30 using namespace FileAccessFwk;
31 using namespace AbilityRuntime;
32
33 template<class T>
TypeCast(const uint8_t * data,int * pos=nullptr)34 T TypeCast(const uint8_t *data, int *pos = nullptr)
35 {
36 if (pos) {
37 *pos += sizeof(T);
38 }
39 return *(reinterpret_cast<const T*>(data));
40 }
41
OnRemoteRequestFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)42 bool OnRemoteRequestFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
43 {
44 if (data == nullptr || size < sizeof(uint32_t)) {
45 return true;
46 }
47
48 uint32_t code = TypeCast<uint32_t>(data);
49 MessageParcel msg;
50 msg.WriteInterfaceToken(FileAccessExtStub::GetDescriptor());
51 MessageParcel reply;
52 MessageOption option;
53
54 fileAccessExtStub->OnRemoteRequest(code, msg, reply, option);
55 return true;
56 }
57
CmdOpenFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)58 bool CmdOpenFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
59 {
60 if (data == nullptr || size < sizeof(int32_t)) {
61 return true;
62 }
63
64 MessageParcel msg;
65 MessageParcel reply;
66 msg.WriteString(string(reinterpret_cast<const char*>(data), size - sizeof(int32_t)));
67 msg.WriteInt32(TypeCast<int32_t>(data));
68
69 fileAccessExtStub->CmdOpenFile(msg, reply);
70 return true;
71 }
72
CmdCreateFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)73 bool CmdCreateFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
74 {
75 MessageParcel msg;
76 MessageParcel reply;
77 int pos = size >> 1;
78 msg.WriteString(string(reinterpret_cast<const char*>(data), pos));
79 msg.WriteString(string(reinterpret_cast<const char*>(data + pos), size - pos));
80
81 fileAccessExtStub->CmdCreateFile(msg, reply);
82 return true;
83 }
84
CmdMkdirFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)85 bool CmdMkdirFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
86 {
87 MessageParcel msg;
88 MessageParcel reply;
89 int pos = size >> 1;
90 msg.WriteString(string(reinterpret_cast<const char*>(data), pos));
91 msg.WriteString(string(reinterpret_cast<const char*>(data + pos), size - pos));
92
93 fileAccessExtStub->CmdMkdir(msg, reply);
94 return true;
95 }
96
CmdDeleteFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)97 bool CmdDeleteFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
98 {
99 MessageParcel msg;
100 MessageParcel reply;
101 msg.WriteString(string(reinterpret_cast<const char*>(data), size));
102
103 fileAccessExtStub->CmdDelete(msg, reply);
104 return true;
105 }
106
CmdMoveFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)107 bool CmdMoveFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
108 {
109 MessageParcel msg;
110 MessageParcel reply;
111 int pos = size >> 1;
112 msg.WriteString(string(reinterpret_cast<const char*>(data), pos));
113 msg.WriteString(string(reinterpret_cast<const char*>(data + pos), size - pos));
114
115 fileAccessExtStub->CmdMove(msg, reply);
116 return true;
117 }
118
CmdCopyFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)119 bool CmdCopyFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
120 {
121 if (data == nullptr || size == 0) {
122 return true;
123 }
124
125 MessageParcel msg;
126 MessageParcel reply;
127 int pos = (size - 1) >> 1;
128 msg.WriteString(string(reinterpret_cast<const char*>(data + 1), pos));
129 msg.WriteString(string(reinterpret_cast<const char*>(data + pos + 1), size - pos - 1));
130 msg.WriteBool(TypeCast<bool>(data));
131
132 fileAccessExtStub->CmdCopy(msg, reply);
133 return true;
134 }
135
CmdCopyFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)136 bool CmdCopyFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
137 {
138 MessageParcel msg;
139 MessageParcel reply;
140 int pos = size / 3;
141 msg.WriteString(string(reinterpret_cast<const char*>(data), pos));
142 msg.WriteString(string(reinterpret_cast<const char*>(data + pos), pos));
143 msg.WriteString(string(reinterpret_cast<const char*>(data + pos + pos), size - pos - pos));
144
145 fileAccessExtStub->CmdCopyFile(msg, reply);
146 return true;
147 }
148
CmdRenameFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)149 bool CmdRenameFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
150 {
151 MessageParcel msg;
152 MessageParcel reply;
153 int pos = size >> 1;
154 msg.WriteString(string(reinterpret_cast<const char*>(data), pos));
155 msg.WriteString(string(reinterpret_cast<const char*>(data + pos), size - pos));
156
157 fileAccessExtStub->CmdRename(msg, reply);
158 return true;
159 }
160
CmdListFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)161 bool CmdListFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
162 {
163 size_t minSize = sizeof(int64_t) + sizeof(int32_t) + sizeof(int64_t) + sizeof(int64_t) + sizeof(int64_t) +
164 sizeof(double) + sizeof(bool) + sizeof(bool);
165 if (data == nullptr || size < minSize) {
166 return true;
167 }
168
169 int pos = 0;
170 int64_t offset = TypeCast<int64_t>(data, &pos);
171 FileInfo fileInfo;
172 fileInfo.mode = TypeCast<int32_t>(data + pos, &pos);
173 fileInfo.size = TypeCast<int64_t>(data + pos, &pos);
174 fileInfo.mtime = TypeCast<int64_t>(data + pos, &pos);
175
176 int64_t fileSizeOver = TypeCast<int64_t>(data + pos, &pos);
177 double lastModifiedAfter = TypeCast<double>(data + pos, &pos);
178 bool excludeMedia = TypeCast<bool>(data + pos, &pos);
179 bool hasFilter = TypeCast<bool>(data + pos, &pos);
180
181 int len = (size - pos) / 6;
182 fileInfo.uri = string(reinterpret_cast<const char*>(data + pos), len);
183 pos += len;
184 fileInfo.relativePath = string(reinterpret_cast<const char*>(data + pos), len);
185 pos += len;
186 fileInfo.fileName = string(reinterpret_cast<const char*>(data + pos), len);
187 pos += len;
188 std::vector<std::string> suffix;
189 suffix.push_back(string(reinterpret_cast<const char*>(data + pos), len));
190 pos += len;
191 std::vector<std::string> displayName;
192 displayName.push_back(string(reinterpret_cast<const char*>(data + pos), len));
193 pos += len;
194 std::vector<std::string> mimeType;
195 mimeType.push_back(string(reinterpret_cast<const char*>(data + pos), len));
196 pos += len;
197 FileFilter fileFilter(suffix, displayName, mimeType, fileSizeOver, lastModifiedAfter, excludeMedia, hasFilter);
198
199 SharedMemoryInfo sharedMemoryInfo;
200 MessageParcel msg;
201 MessageParcel reply;
202 msg.WriteParcelable(&fileInfo);
203 msg.WriteInt64(offset);
204 msg.WriteParcelable(&fileFilter);
205 msg.WriteParcelable(&sharedMemoryInfo);
206
207 fileAccessExtStub->CmdListFile(msg, reply);
208 return true;
209 }
210
CmdScanFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)211 bool CmdScanFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
212 {
213 size_t minSize = sizeof(int64_t) + sizeof(int64_t) + sizeof(int32_t) + sizeof(int64_t) + sizeof(int64_t) +
214 sizeof(int64_t) + sizeof(double) + sizeof(bool) + sizeof(bool);
215 if (data == nullptr || size < minSize) {
216 return true;
217 }
218
219 int pos = 0;
220 int64_t offset = TypeCast<int64_t>(data, &pos);
221 int64_t maxCount = TypeCast<int64_t>(data, &pos);
222 FileInfo fileInfo;
223 fileInfo.mode = TypeCast<int32_t>(data + pos, &pos);
224 fileInfo.size = TypeCast<int64_t>(data + pos, &pos);
225 fileInfo.mtime = TypeCast<int64_t>(data + pos, &pos);
226
227 int64_t fileSizeOver = TypeCast<int64_t>(data + pos, &pos);
228 double lastModifiedAfter = TypeCast<double>(data + pos, &pos);
229 bool excludeMedia = TypeCast<bool>(data + pos, &pos);
230 bool hasFilter = TypeCast<bool>(data + pos, &pos);
231
232 int len = (size - pos) / 6;
233 fileInfo.uri = string(reinterpret_cast<const char*>(data + pos), len);
234 pos += len;
235 fileInfo.relativePath = string(reinterpret_cast<const char*>(data + pos), len);
236 pos += len;
237 fileInfo.fileName = string(reinterpret_cast<const char*>(data + pos), len);
238 pos += len;
239 std::vector<std::string> suffix;
240 suffix.push_back(string(reinterpret_cast<const char*>(data + pos), len));
241 pos += len;
242 std::vector<std::string> displayName;
243 displayName.push_back(string(reinterpret_cast<const char*>(data + pos), len));
244 pos += len;
245 std::vector<std::string> mimeType;
246 mimeType.push_back(string(reinterpret_cast<const char*>(data + pos), len));
247 pos += len;
248 FileFilter fileFilter(suffix, displayName, mimeType, fileSizeOver, lastModifiedAfter, excludeMedia, hasFilter);
249
250 SharedMemoryInfo sharedMemoryInfo;
251 MessageParcel msg;
252 MessageParcel reply;
253 msg.WriteParcelable(&fileInfo);
254 msg.WriteInt64(offset);
255 msg.WriteInt64(maxCount);
256 msg.WriteParcelable(&fileFilter);
257
258 fileAccessExtStub->CmdScanFile(msg, reply);
259 return true;
260 }
261
CmdGetRootsFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)262 bool CmdGetRootsFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
263 {
264 MessageParcel msg;
265 MessageParcel reply;
266
267 fileAccessExtStub->CmdGetRoots(msg, reply);
268 return true;
269 }
270
CmdQueryFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)271 bool CmdQueryFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
272 {
273 if (data == nullptr || size < sizeof(int64_t)) {
274 return true;
275 }
276
277 MessageParcel msg;
278 MessageParcel reply;
279 msg.WriteString(string(reinterpret_cast<const char*>(data + sizeof(int64_t)), size - sizeof(int64_t)));
280 msg.WriteInt64(TypeCast<int64_t>(data));
281
282 fileAccessExtStub->CmdQuery(msg, reply);
283 return true;
284 }
285
CmdGetFileInfoFromUriFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)286 bool CmdGetFileInfoFromUriFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
287 {
288 MessageParcel msg;
289 MessageParcel reply;
290 msg.WriteString(string(reinterpret_cast<const char*>(data), size));
291
292 fileAccessExtStub->CmdGetFileInfoFromUri(msg, reply);
293 return true;
294 }
295
CmdGetFileInfoFromRelativePathFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)296 bool CmdGetFileInfoFromRelativePathFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data,
297 size_t size)
298 {
299 MessageParcel msg;
300 MessageParcel reply;
301 msg.WriteString(string(reinterpret_cast<const char*>(data), size));
302
303 fileAccessExtStub->CmdGetFileInfoFromRelativePath(msg, reply);
304 return true;
305 }
306
CmdAccessFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)307 bool CmdAccessFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
308 {
309 MessageParcel msg;
310 MessageParcel reply;
311 msg.WriteString(string(reinterpret_cast<const char*>(data), size));
312
313 fileAccessExtStub->CmdAccess(msg, reply);
314 return true;
315 }
316
CmdStartWatcherFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)317 bool CmdStartWatcherFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
318 {
319 MessageParcel msg;
320 MessageParcel reply;
321 msg.WriteString(string(reinterpret_cast<const char*>(data), size));
322
323 fileAccessExtStub->CmdStartWatcher(msg, reply);
324 return true;
325 }
326
CmdStopWatcherFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)327 bool CmdStopWatcherFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
328 {
329 MessageParcel msg;
330 MessageParcel reply;
331 msg.WriteString(string(reinterpret_cast<const char*>(data), size));
332
333 fileAccessExtStub->CmdStopWatcher(msg, reply);
334 return true;
335 }
336
CmdMoveItemFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)337 bool CmdMoveItemFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
338 {
339 if (data == nullptr || size == 0) {
340 return true;
341 }
342
343 MessageParcel msg;
344 MessageParcel reply;
345 int pos = (size - 1) >> 1;
346 msg.WriteString(string(reinterpret_cast<const char*>(data + 1), pos));
347 msg.WriteString(string(reinterpret_cast<const char*>(data + pos + 1), size - pos - 1));
348 msg.WriteBool(TypeCast<bool>(data));
349
350 fileAccessExtStub->CmdMoveItem(msg, reply);
351 return true;
352 }
353
CmdMoveFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub,const uint8_t * data,size_t size)354 bool CmdMoveFileFuzzTest(shared_ptr<FileAccessExtStub> fileAccessExtStub, const uint8_t *data, size_t size)
355 {
356 MessageParcel msg;
357 MessageParcel reply;
358 int pos = size / 3;
359 msg.WriteString(string(reinterpret_cast<const char*>(data), pos));
360 msg.WriteString(string(reinterpret_cast<const char*>(data + pos), pos));
361 msg.WriteString(string(reinterpret_cast<const char*>(data + pos + pos), size - pos - pos));
362
363 fileAccessExtStub->CmdMoveFile(msg, reply);
364 return true;
365 }
366
367 } // namespace OHOS
368
369 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)370 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
371 {
372 auto ability = std::make_shared<OHOS::FileAccessFwk::FileAccessExtAbilityMock>();
373 auto stub = std::make_shared<OHOS::FileAccessFwk::FileAccessExtStubImpl>(ability, nullptr);
374 if (stub == nullptr) {
375 return 0;
376 }
377
378 OHOS::OnRemoteRequestFuzzTest(stub, data, size);
379 OHOS::CmdOpenFileFuzzTest(stub, data, size);
380 OHOS::CmdCreateFileFuzzTest(stub, data, size);
381 OHOS::CmdMkdirFuzzTest(stub, data, size);
382 OHOS::CmdDeleteFuzzTest(stub, data, size);
383 OHOS::CmdMoveFuzzTest(stub, data, size);
384 OHOS::CmdCopyFuzzTest(stub, data, size);
385 OHOS::CmdCopyFileFuzzTest(stub, data, size);
386 OHOS::CmdRenameFuzzTest(stub, data, size);
387 OHOS::CmdListFileFuzzTest(stub, data, size);
388 OHOS::CmdScanFileFuzzTest(stub, data, size);
389 OHOS::CmdGetRootsFuzzTest(stub, data, size);
390 OHOS::CmdQueryFuzzTest(stub, data, size);
391 OHOS::CmdGetFileInfoFromUriFuzzTest(stub, data, size);
392 OHOS::CmdGetFileInfoFromRelativePathFuzzTest(stub, data, size);
393 OHOS::CmdAccessFuzzTest(stub, data, size);
394 OHOS::CmdStartWatcherFuzzTest(stub, data, size);
395 OHOS::CmdStopWatcherFuzzTest(stub, data, size);
396 OHOS::CmdMoveItemFuzzTest(stub, data, size);
397 OHOS::CmdMoveFileFuzzTest(stub, data, size);
398 return 0;
399 }
400