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 if ((data == nullptr) || (size <= 0)) {
141 HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
142 return false;
143 }
144 helper = GetFileAccessHelper();
145 if (helper == nullptr) {
146 HILOG_ERROR("GetFileAccessHelper return nullptr.");
147 return false;
148 }
149 return true;
150 }
151
AccessFuzzTest(const uint8_t * data,size_t size)152 bool AccessFuzzTest(const uint8_t* data, size_t size)
153 {
154 shared_ptr<FileAccessHelper> helper;
155 if (!CheckDataAndHelper(data, size, helper)) {
156 return false;
157 }
158 Uri uri(std::string(reinterpret_cast<const char*>(data), size));
159 bool isExist = false;
160 int result = helper->Access(uri, isExist);
161 if (isExist != true || result != OHOS::FileAccessFwk::ERR_OK) {
162 return false;
163 }
164 return true;
165 }
166
OpenFileFuzzTest(const uint8_t * data,size_t size)167 bool OpenFileFuzzTest(const uint8_t* data, size_t size)
168 {
169 shared_ptr<FileAccessHelper> helper;
170 if (!CheckDataAndHelper(data, size, helper)) {
171 return false;
172 }
173 Uri uri(std::string(reinterpret_cast<const char*>(data), size));
174 int fd = -1;
175 int result = 0;
176 result = helper->OpenFile(uri, WRITE_READ, fd);
177 if (result != OHOS::FileAccessFwk::ERR_OK) {
178 HILOG_ERROR("OpenFile failed. ret : %{public}d", result);
179 return false;
180 }
181 close(fd);
182 return true;
183 }
184
CreateFileFuzzTest(const uint8_t * data,size_t size)185 bool CreateFileFuzzTest(const uint8_t* data, size_t size)
186 {
187 shared_ptr<FileAccessHelper> helper;
188 if (!CheckDataAndHelper(data, size, helper)) {
189 return false;
190 }
191
192 vector<RootInfo> info;
193 int result = helper->GetRoots(info);
194 if (result != OHOS::FileAccessFwk::ERR_OK) {
195 HILOG_ERROR("GetRoots failed. ret : %{public}d", result);
196 return false;
197 }
198 for (size_t i = 0; i < info.size(); i++) {
199 Uri parentUri(info[i].uri);
200 Uri newFileUri("");
201 result = helper->CreateFile(parentUri, "CreateFileFuzzTest", newFileUri);
202 if (result != OHOS::FileAccessFwk::ERR_OK) {
203 HILOG_ERROR("CreateFile failed. ret : %{public}d", result);
204 return false;
205 }
206 result = helper->Delete(newFileUri);
207 if (result != OHOS::FileAccessFwk::ERR_OK) {
208 HILOG_ERROR("Delete failed. ret : %{public}d", result);
209 return false;
210 }
211 }
212 return true;
213 }
214
MkdirFuzzTest(const uint8_t * data,size_t size)215 bool MkdirFuzzTest(const uint8_t* data, size_t size)
216 {
217 shared_ptr<FileAccessHelper> helper;
218 if (!CheckDataAndHelper(data, size, helper)) {
219 return false;
220 }
221
222 vector<RootInfo> info;
223 int result = helper->GetRoots(info);
224 if (result != OHOS::FileAccessFwk::ERR_OK) {
225 HILOG_ERROR("GetRoots failed. ret : %{public}d", result);
226 return false;
227 }
228 for (size_t i = 0; i < info.size(); i++) {
229 Uri parentUri(info[i].uri);
230 Uri newDirUri("");
231 result = helper->Mkdir(parentUri, "MkdirFuzzTest", newDirUri);
232 if (result != OHOS::FileAccessFwk::ERR_OK) {
233 HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
234 return false;
235 }
236 result = helper->Delete(newDirUri);
237 if (result != OHOS::FileAccessFwk::ERR_OK) {
238 HILOG_ERROR("Delete failed. ret : %{public}d", result);
239 return false;
240 }
241 }
242 return true;
243 }
244
DeleteFuzzTest(const uint8_t * data,size_t size)245 bool DeleteFuzzTest(const uint8_t* data, size_t size)
246 {
247 shared_ptr<FileAccessHelper> helper;
248 if (!CheckDataAndHelper(data, size, helper)) {
249 return false;
250 }
251 Uri uri(std::string(reinterpret_cast<const char*>(data), size));
252 int result = helper->Delete(uri);
253 if (result != OHOS::FileAccessFwk::ERR_OK) {
254 HILOG_ERROR("Delete failed. ret : %{public}d", result);
255 return false;
256 }
257 return true;
258 }
259
MoveFuzzTest(const uint8_t * data,size_t size)260 bool MoveFuzzTest(const uint8_t* data, size_t size)
261 {
262 shared_ptr<FileAccessHelper> helper;
263 if (!CheckDataAndHelper(data, size, helper)) {
264 return false;
265 }
266 vector<RootInfo> info;
267 int result = helper->GetRoots(info);
268 if (result != OHOS::FileAccessFwk::ERR_OK) {
269 return false;
270 }
271 for (size_t i = 0; i < info.size(); i++) {
272 Uri parentUri(info[i].uri);
273 Uri newDirUriTest1("");
274 Uri newDirUriTest2("");
275 int result1 = helper->Mkdir(parentUri, "test1", newDirUriTest1);
276 int result2 = helper->Mkdir(parentUri, "test2", newDirUriTest2);
277 if (result1 != OHOS::FileAccessFwk::ERR_OK || result2 != OHOS::FileAccessFwk::ERR_OK) {
278 HILOG_ERROR("Mkdir failed. ret : %{public}d, %{public}d", result1, result2);
279 return false;
280 }
281 Uri testUri("");
282 result = helper->CreateFile(newDirUriTest1, "test.txt", testUri);
283 if (result != OHOS::FileAccessFwk::ERR_OK) {
284 HILOG_ERROR("CreateFile failed. ret : %{public}d", result);
285 return false;
286 }
287 Uri testUri2("");
288 result = helper->Move(testUri, newDirUriTest2, testUri2);
289 if (result != OHOS::FileAccessFwk::ERR_OK) {
290 HILOG_ERROR("Move failed. ret : %{public}d", result);
291 return false;
292 }
293 result1 = helper->Delete(newDirUriTest1);
294 result2 = helper->Delete(newDirUriTest2);
295 if (result1 != OHOS::FileAccessFwk::ERR_OK || result2 != OHOS::FileAccessFwk::ERR_OK) {
296 HILOG_ERROR("Delete failed. ret : %{public}d, %{public}d", result1, result2);
297 return false;
298 }
299 }
300 return true;
301 }
302
RenameFuzzTest(const uint8_t * data,size_t size)303 bool RenameFuzzTest(const uint8_t* data, size_t size)
304 {
305 shared_ptr<FileAccessHelper> helper;
306 if (!CheckDataAndHelper(data, size, helper)) {
307 return false;
308 }
309 vector<RootInfo> info;
310 int result = helper->GetRoots(info);
311 if (result != OHOS::FileAccessFwk::ERR_OK) {
312 HILOG_ERROR("GetRoots failed. ret : %{public}d", result);
313 return false;
314 }
315 for (size_t i = 0; i < info.size(); i++) {
316 Uri parentUri(info[i].uri);
317 Uri newDirUriTest("");
318 result = helper->Mkdir(parentUri, "test", newDirUriTest);
319 if (result != OHOS::FileAccessFwk::ERR_OK) {
320 HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
321 return false;
322 }
323 Uri renameUri("");
324 result = helper->Rename(newDirUriTest, "testRename", renameUri);
325 if (result != OHOS::FileAccessFwk::ERR_OK) {
326 HILOG_ERROR("Rename failed. ret : %{public}d", result);
327 return false;
328 }
329 result = helper->Delete(renameUri);
330 if (result != OHOS::FileAccessFwk::ERR_OK) {
331 HILOG_ERROR("Delete failed. ret : %{public}d", result);
332 return false;
333 }
334 }
335 return true;
336 }
337
ListFileFuzzTest(const uint8_t * data,size_t size)338 bool ListFileFuzzTest(const uint8_t* data, size_t size)
339 {
340 if ((data == nullptr) || (size == 0)) {
341 HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
342 return false;
343 }
344 shared_ptr<FileAccessHelper> helper = GetFileAccessHelper();
345 if (helper == nullptr) {
346 HILOG_ERROR("GetFileAccessHelper return nullptr.");
347 return false;
348 }
349
350 FileInfo fileInfo;
351 fileInfo.uri = std::string(reinterpret_cast<const char*>(data), size);
352 int64_t offset = 0;
353 SharedMemoryInfo memInfo;
354 int result = SharedMemoryOperation::CreateSharedMemory("FileInfo List", DEFAULT_CAPACITY_200KB,
355 memInfo);
356 if (result != OHOS::FileAccessFwk::ERR_OK) {
357 HILOG_ERROR("CreateSharedMemory failed. ret : %{public}d", result);
358 return false;
359 }
360 FileFilter filter;
361 result = helper->ListFile(fileInfo, offset, filter, memInfo);
362 SharedMemoryOperation::DestroySharedMemory(memInfo);
363 if (result != OHOS::FileAccessFwk::ERR_OK) {
364 HILOG_ERROR("ListFile failed. ret : %{public}d", result);
365 return false;
366 }
367 return true;
368 }
369
ScanFileFuzzTest(const uint8_t * data,size_t size)370 bool ScanFileFuzzTest(const uint8_t* data, size_t size)
371 {
372 if ((data == nullptr) || (size == 0)) {
373 HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
374 return false;
375 }
376 shared_ptr<FileAccessHelper> helper = GetFileAccessHelper();
377 if (helper == nullptr) {
378 HILOG_ERROR("GetFileAccessHelper return nullptr.");
379 return false;
380 }
381
382 FileInfo fileInfo;
383 fileInfo.uri = std::string(reinterpret_cast<const char*>(data), size);
384 int64_t offset = 0;
385 int64_t maxCount = 1000;
386 std::vector<FileInfo> fileInfoVec;
387 FileFilter filter;
388 int result = helper->ScanFile(fileInfo, offset, maxCount, filter, fileInfoVec);
389 if (result != OHOS::FileAccessFwk::ERR_OK) {
390 HILOG_ERROR("ScanFile failed. ret : %{public}d", result);
391 return false;
392 }
393 return true;
394 }
395
GetFileInfoFromUriFuzzTest(const uint8_t * data,size_t size)396 bool GetFileInfoFromUriFuzzTest(const uint8_t* data, size_t size)
397 {
398 if ((data == nullptr) || (size == 0)) {
399 HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
400 return false;
401 }
402 Uri uri(std::string(reinterpret_cast<const char*>(data), size));
403 shared_ptr<FileAccessHelper> helper = GetFileAccessHelper();
404 if (helper == nullptr) {
405 HILOG_ERROR("GetFileAccessHelper return nullptr.");
406 return false;
407 }
408 FileInfo fileinfo;
409 int result = helper->GetFileInfoFromUri(uri, fileinfo);
410 if (result != OHOS::FileAccessFwk::ERR_OK) {
411 HILOG_ERROR("GetFileInfoFromUri failed. ret : %{public}d", result);
412 return false;
413 }
414 return true;
415 }
416
417 }
418
419 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)420 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
421 {
422 /* Run your code on data */
423 OHOS::CreatorFuzzTest(data, size);
424 OHOS::AccessFuzzTest(data, size);
425 OHOS::OpenFileFuzzTest(data, size);
426 OHOS::MkdirFuzzTest(data, size);
427 OHOS::CreateFileFuzzTest(data, size);
428 OHOS::DeleteFuzzTest(data, size);
429 OHOS::MoveFuzzTest(data, size);
430 OHOS::RenameFuzzTest(data, size);
431 OHOS::ListFileFuzzTest(data, size);
432 OHOS::ScanFileFuzzTest(data, size);
433 OHOS::GetFileInfoFromUriFuzzTest(data, size);
434 return 0;
435 }
436