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 }