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