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