• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 
16 #include "external_file_access_fuzzer.h"
17 
18 #include <cstdio>
19 #include <thread>
20 #include <unistd.h>
21 
22 #include "accesstoken_kit.h"
23 #include "token_setproc.h"
24 #include "nativetoken_kit.h"
25 #include "file_access_framework_errno.h"
26 #include "file_access_helper.h"
27 #include "file_info_shared_memory.h"
28 #include "iservice_registry.h"
29 #include "hilog_wrapper.h"
30 
31 namespace OHOS {
32 using namespace std;
33 using namespace OHOS;
34 using namespace FileAccessFwk;
35 
36 const int ABILITY_ID = 5003;
37 shared_ptr<FileAccessHelper> g_fah = nullptr;
38 const int UID_TRANSFORM_TMP = 20000000;
39 const int UID_DEFAULT = 0;
40 
SetNativeToken()41 void SetNativeToken()
42 {
43     uint64_t tokenId;
44     const char *perms[] = {
45         "ohos.permission.FILE_ACCESS_MANAGER",
46         "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED",
47         "ohos.permission.CONNECT_FILE_ACCESS_EXTENSION"
48     };
49     NativeTokenInfoParams infoInstance = {
50         .dcapsNum = 0,
51         .permsNum = 3,
52         .aclsNum = 0,
53         .dcaps = nullptr,
54         .perms = perms,
55         .acls = nullptr,
56         .aplStr = "system_core",
57     };
58 
59     infoInstance.processName = "SetUpTestCase";
60     tokenId = GetAccessTokenId(&infoInstance);
61     const uint64_t systemAppMask = (static_cast<uint64_t>(1) << 32);
62     tokenId |= systemAppMask;
63     SetSelfTokenID(tokenId);
64     OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
65 }
66 
GetFileAccessHelper()67 shared_ptr<FileAccessHelper> GetFileAccessHelper()
68 {
69     if (g_fah != nullptr) {
70         return g_fah;
71     }
72     SetNativeToken();
73     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
74     if (saManager == nullptr) {
75         return nullptr;
76     }
77     auto remoteObj = saManager->GetSystemAbility(ABILITY_ID);
78     AAFwk::Want want;
79     vector<AAFwk::Want> wantVec;
80     setuid(UID_TRANSFORM_TMP);
81     int ret = FileAccessHelper::GetRegisteredFileAccessExtAbilityInfo(wantVec);
82     if (ret != OHOS::FileAccessFwk::ERR_OK) {
83         HILOG_ERROR("GetRegisteredFileAccessExtAbilityInfo failed.");
84         return nullptr;
85     }
86     bool sus = false;
87     for (size_t i = 0; i < wantVec.size(); i++) {
88         auto element = wantVec[i].GetElement();
89         if (element.GetBundleName() == "com.ohos.UserFile.ExternalFileManager" &&
90             element.GetAbilityName() == "FileExtensionAbility") {
91             want = wantVec[i];
92             sus = true;
93             break;
94         }
95     }
96     if (!sus) {
97         HILOG_ERROR("not found bundleName.");
98         return nullptr;
99     }
100     vector<AAFwk::Want> wants {want};
101     g_fah = FileAccessHelper::Creator(remoteObj, wants);
102     setuid(UID_DEFAULT);
103     if (g_fah == nullptr) {
104         HILOG_ERROR("creator fileAccessHelper return nullptr.");
105         return nullptr;
106     }
107     return g_fah;
108 }
109 
CreatorFuzzTest(const uint8_t * data,size_t size)110 bool CreatorFuzzTest(const uint8_t* data, size_t size)
111 {
112     SetNativeToken();
113     if ((data == nullptr) || (size <= 0)) {
114         HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
115         return false;
116     }
117     std::string bundleName(reinterpret_cast<const char*>(data), size);
118     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
119     if (saManager == nullptr) {
120         return false;
121     }
122     auto remoteObj = saManager->GetSystemAbility(ABILITY_ID);
123     AAFwk::Want want;
124     want.SetElementName(bundleName, "FileExtensionAbility");
125     vector<AAFwk::Want> wants {want};
126     setuid(UID_TRANSFORM_TMP);
127     shared_ptr<FileAccessHelper> helper = nullptr;
128     helper = FileAccessHelper::Creator(remoteObj, wants);
129     setuid(UID_DEFAULT);
130     if (helper == nullptr) {
131         HILOG_ERROR("creator return nullptr.");
132         return false;
133     }
134     helper->Release();
135     return true;
136 }
137 
CheckDataAndHelper(const uint8_t * data,size_t size,shared_ptr<FileAccessHelper> & helper)138 bool CheckDataAndHelper(const uint8_t* data, size_t size, shared_ptr<FileAccessHelper>& helper)
139 {
140     (void)data;
141     helper = GetFileAccessHelper();
142     if (helper == nullptr) {
143         HILOG_ERROR("GetFileAccessHelper return nullptr.");
144         return false;
145     }
146     return true;
147 }
148 
AccessFuzzTest(const uint8_t * data,size_t size)149 bool AccessFuzzTest(const uint8_t* data, size_t size)
150 {
151     shared_ptr<FileAccessHelper> helper;
152     if (!CheckDataAndHelper(data, size, helper)) {
153         return false;
154     }
155     Uri uri(std::string(reinterpret_cast<const char*>(data), size));
156     bool isExist = false;
157     int result = helper->Access(uri, isExist);
158     if (isExist != true || result != OHOS::FileAccessFwk::ERR_OK) {
159         return false;
160     }
161     return true;
162 }
163 
OpenFileFuzzTest(const uint8_t * data,size_t size)164 bool OpenFileFuzzTest(const uint8_t* data, size_t size)
165 {
166     shared_ptr<FileAccessHelper> helper;
167     if (!CheckDataAndHelper(data, size, helper)) {
168         return false;
169     }
170     Uri uri(std::string(reinterpret_cast<const char*>(data), size));
171     int fd = -1;
172     int result = 0;
173     result = helper->OpenFile(uri, WRITE_READ, fd);
174     if (result != OHOS::FileAccessFwk::ERR_OK) {
175         HILOG_ERROR("OpenFile failed. ret : %{public}d", result);
176         return false;
177     }
178     close(fd);
179     return true;
180 }
181 
CreateFileFuzzTest(const uint8_t * data,size_t size)182 bool CreateFileFuzzTest(const uint8_t* data, size_t size)
183 {
184     shared_ptr<FileAccessHelper> helper;
185     if (!CheckDataAndHelper(data, size, helper)) {
186         return false;
187     }
188 
189     vector<RootInfo> info;
190     int result = helper->GetRoots(info);
191     if (result != OHOS::FileAccessFwk::ERR_OK) {
192         HILOG_ERROR("GetRoots failed. ret : %{public}d", result);
193         return false;
194     }
195     for (size_t i = 0; i < info.size(); i++) {
196         Uri parentUri(info[i].uri);
197         Uri newFileUri("");
198         result = helper->CreateFile(parentUri, "CreateFileFuzzTest", newFileUri);
199         if (result != OHOS::FileAccessFwk::ERR_OK) {
200             HILOG_ERROR("CreateFile failed. ret : %{public}d", result);
201             return false;
202         }
203         result = helper->Delete(newFileUri);
204         if (result != OHOS::FileAccessFwk::ERR_OK) {
205             HILOG_ERROR("Delete failed. ret : %{public}d", result);
206             return false;
207         }
208     }
209     return true;
210 }
211 
MkdirFuzzTest(const uint8_t * data,size_t size)212 bool MkdirFuzzTest(const uint8_t* data, size_t size)
213 {
214     shared_ptr<FileAccessHelper> helper;
215     if (!CheckDataAndHelper(data, size, helper)) {
216         return false;
217     }
218 
219     vector<RootInfo> info;
220     int result = helper->GetRoots(info);
221     if (result != OHOS::FileAccessFwk::ERR_OK) {
222         HILOG_ERROR("GetRoots failed. ret : %{public}d", result);
223         return false;
224     }
225     for (size_t i = 0; i < info.size(); i++) {
226         Uri parentUri(info[i].uri);
227         Uri newDirUri("");
228         std::string dirName(reinterpret_cast<const char*>(data), size);
229         result = helper->Mkdir(parentUri, dirName, newDirUri);
230         if (result != OHOS::FileAccessFwk::ERR_OK) {
231             HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
232             return false;
233         }
234         result = helper->Delete(newDirUri);
235         if (result != OHOS::FileAccessFwk::ERR_OK) {
236             HILOG_ERROR("Delete failed. ret : %{public}d", result);
237             return false;
238         }
239     }
240     return true;
241 }
242 
DeleteFuzzTest(const uint8_t * data,size_t size)243 bool DeleteFuzzTest(const uint8_t* data, size_t size)
244 {
245     shared_ptr<FileAccessHelper> helper;
246     if (!CheckDataAndHelper(data, size, helper)) {
247         return false;
248     }
249     Uri uri(std::string(reinterpret_cast<const char*>(data), size));
250     int result = helper->Delete(uri);
251     if (result != OHOS::FileAccessFwk::ERR_OK) {
252         HILOG_ERROR("Delete failed. ret : %{public}d", result);
253         return false;
254     }
255     return true;
256 }
257 
MoveFuzzTest(const uint8_t * data,size_t size)258 bool MoveFuzzTest(const uint8_t* data, size_t size)
259 {
260     shared_ptr<FileAccessHelper> helper;
261     if (!CheckDataAndHelper(data, size, helper)) {
262         return false;
263     }
264     vector<RootInfo> info;
265     int result = helper->GetRoots(info);
266     if (result != OHOS::FileAccessFwk::ERR_OK) {
267         return false;
268     }
269     for (size_t i = 0; i < info.size(); i++) {
270         Uri parentUri(info[i].uri);
271         Uri newDirUriTest1("");
272         Uri newDirUriTest2("");
273         size_t len = size >> 2;
274         std::string test1(reinterpret_cast<const char*>(data), len);
275         std::string test2(reinterpret_cast<const char*>(data + len), len);
276         int result1 = helper->Mkdir(parentUri, test1, newDirUriTest1);
277         int result2 = helper->Mkdir(parentUri, test2, newDirUriTest2);
278         if (result1 != OHOS::FileAccessFwk::ERR_OK || result2 != OHOS::FileAccessFwk::ERR_OK) {
279             HILOG_ERROR("Mkdir failed. ret : %{public}d, %{public}d", result1, result2);
280             return false;
281         }
282         Uri testUri("");
283         std::string test(reinterpret_cast<const char*>(data + len + len), len);
284         result = helper->CreateFile(newDirUriTest1, test, testUri);
285         if (result != OHOS::FileAccessFwk::ERR_OK) {
286             HILOG_ERROR("CreateFile failed. ret : %{public}d", result);
287             return false;
288         }
289         Uri testUri2("");
290         result = helper->Move(testUri, newDirUriTest2, testUri2);
291         if (result != OHOS::FileAccessFwk::ERR_OK) {
292             HILOG_ERROR("Move failed. ret : %{public}d", result);
293             return false;
294         }
295         result1 = helper->Delete(newDirUriTest1);
296         result2 = helper->Delete(newDirUriTest2);
297         if (result1 != OHOS::FileAccessFwk::ERR_OK || result2 != OHOS::FileAccessFwk::ERR_OK) {
298             HILOG_ERROR("Delete failed. ret : %{public}d, %{public}d", result1, result2);
299             return false;
300         }
301     }
302     return true;
303 }
304 
RenameFuzzTest(const uint8_t * data,size_t size)305 bool RenameFuzzTest(const uint8_t* data, size_t size)
306 {
307     shared_ptr<FileAccessHelper> helper;
308     if (!CheckDataAndHelper(data, size, helper)) {
309         return false;
310     }
311     vector<RootInfo> info;
312     int result = helper->GetRoots(info);
313     if (result != OHOS::FileAccessFwk::ERR_OK) {
314         HILOG_ERROR("GetRoots failed. ret : %{public}d", result);
315         return false;
316     }
317     for (size_t i = 0; i < info.size(); i++) {
318         Uri parentUri(info[i].uri);
319         Uri newDirUriTest("");
320         result = helper->Mkdir(parentUri, "test", newDirUriTest);
321         if (result != OHOS::FileAccessFwk::ERR_OK) {
322             HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
323             return false;
324         }
325         Uri renameUri("");
326         std::string testRename(reinterpret_cast<const char*>(data), size);
327         result = helper->Rename(newDirUriTest, testRename, renameUri);
328         if (result != OHOS::FileAccessFwk::ERR_OK) {
329             HILOG_ERROR("Rename failed. ret : %{public}d", result);
330             return false;
331         }
332         result = helper->Delete(renameUri);
333         if (result != OHOS::FileAccessFwk::ERR_OK) {
334             HILOG_ERROR("Delete failed. ret : %{public}d", result);
335             return false;
336         }
337     }
338     return true;
339 }
340 
ListFileFuzzTest(const uint8_t * data,size_t size)341 bool ListFileFuzzTest(const uint8_t* data, size_t size)
342 {
343     if ((data == nullptr) || (size == 0)) {
344         HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
345         return false;
346     }
347     shared_ptr<FileAccessHelper> helper = GetFileAccessHelper();
348     if (helper == nullptr) {
349         HILOG_ERROR("GetFileAccessHelper return nullptr.");
350         return false;
351     }
352 
353     FileInfo fileInfo;
354     fileInfo.uri = std::string(reinterpret_cast<const char*>(data), size);
355     int64_t offset = 0;
356     SharedMemoryInfo memInfo;
357     int result = SharedMemoryOperation::CreateSharedMemory("FileInfo List", DEFAULT_CAPACITY_200KB,
358         memInfo);
359     if (result != OHOS::FileAccessFwk::ERR_OK) {
360         HILOG_ERROR("CreateSharedMemory failed. ret : %{public}d", result);
361         return false;
362     }
363     FileFilter filter;
364     result = helper->ListFile(fileInfo, offset, filter, memInfo);
365     SharedMemoryOperation::DestroySharedMemory(memInfo);
366     if (result != OHOS::FileAccessFwk::ERR_OK) {
367         HILOG_ERROR("ListFile failed. ret : %{public}d", result);
368         return false;
369     }
370     return true;
371 }
372 
ScanFileFuzzTest(const uint8_t * data,size_t size)373 bool ScanFileFuzzTest(const uint8_t* data, size_t size)
374 {
375     if ((data == nullptr) || (size == 0)) {
376         HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
377         return false;
378     }
379     shared_ptr<FileAccessHelper> helper = GetFileAccessHelper();
380     if (helper == nullptr) {
381         HILOG_ERROR("GetFileAccessHelper return nullptr.");
382         return false;
383     }
384 
385     FileInfo fileInfo;
386     fileInfo.uri = std::string(reinterpret_cast<const char*>(data), size);
387     int64_t offset = 0;
388     int64_t maxCount = 1000;
389     std::vector<FileInfo> fileInfoVec;
390     FileFilter filter;
391     int result = helper->ScanFile(fileInfo, offset, maxCount, filter, fileInfoVec);
392     if (result != OHOS::FileAccessFwk::ERR_OK) {
393         HILOG_ERROR("ScanFile failed. ret : %{public}d", result);
394         return false;
395     }
396     return true;
397 }
398 
GetFileInfoFromUriFuzzTest(const uint8_t * data,size_t size)399 bool GetFileInfoFromUriFuzzTest(const uint8_t* data, size_t size)
400 {
401     if ((data == nullptr) || (size == 0)) {
402         HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
403         return false;
404     }
405     Uri uri(std::string(reinterpret_cast<const char*>(data), size));
406     shared_ptr<FileAccessHelper> helper = GetFileAccessHelper();
407     if (helper == nullptr) {
408         HILOG_ERROR("GetFileAccessHelper return nullptr.");
409         return false;
410     }
411     FileInfo fileinfo;
412     int result = helper->GetFileInfoFromUri(uri, fileinfo);
413     if (result != OHOS::FileAccessFwk::ERR_OK) {
414         HILOG_ERROR("GetFileInfoFromUri failed. ret : %{public}d", result);
415         return false;
416     }
417     return true;
418 }
419 
420 }
421 
422 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)423 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
424 {
425     /* Run your code on data */
426     OHOS::CreatorFuzzTest(data, size);
427     OHOS::AccessFuzzTest(data, size);
428     OHOS::OpenFileFuzzTest(data, size);
429     OHOS::MkdirFuzzTest(data, size);
430     OHOS::CreateFileFuzzTest(data, size);
431     OHOS::DeleteFuzzTest(data, size);
432     OHOS::MoveFuzzTest(data, size);
433     OHOS::RenameFuzzTest(data, size);
434     OHOS::ListFileFuzzTest(data, size);
435     OHOS::ScanFileFuzzTest(data, size);
436     OHOS::GetFileInfoFromUriFuzzTest(data, size);
437     return 0;
438 }
439