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