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[] = {
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.medialibrary.medialibrarydata" &&
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 if (g_fah == nullptr) {
103 HILOG_ERROR("creator fileAccessHelper return nullptr.");
104 return nullptr;
105 }
106 setuid(UID_DEFAULT);
107 return g_fah;
108 }
109
CheckDataAndGetDownloadUri(const uint8_t * data,size_t size,shared_ptr<FileAccessHelper> & helper,Uri & downloadUri)110 bool CheckDataAndGetDownloadUri(const uint8_t* data, size_t size, shared_ptr<FileAccessHelper>& helper,
111 Uri& downloadUri)
112 {
113 if ((data == nullptr) || (size <= 0)) {
114 HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
115 return false;
116 }
117 std::tie(helper, downloadUri) = GetDownloadUri();
118 if (helper == nullptr || downloadUri.ToString() == "") {
119 HILOG_ERROR("helper is nullptr or downloadUri is empty");
120 return false;
121 }
122 return true;
123 }
124
CreatorFuzzTest(const uint8_t * data,size_t size)125 bool CreatorFuzzTest(const uint8_t* data, size_t size)
126 {
127 SetNativeToken();
128 if ((data == nullptr) || (size <= 0)) {
129 HILOG_ERROR("parameter data is nullptr or parameter size <= 0.");
130 return false;
131 }
132 std::string bundleName(reinterpret_cast<const char*>(data), size);
133 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
134 if (saManager == nullptr) {
135 return nullptr;
136 }
137 auto remoteObj = saManager->GetSystemAbility(ABILITY_ID);
138 AAFwk::Want want;
139 want.SetElementName(bundleName, "FileExtensionAbility");
140 vector<AAFwk::Want> wants {want};
141 setuid(UID_TRANSFORM_TMP);
142 shared_ptr<FileAccessHelper> helper = nullptr;
143 helper = FileAccessHelper::Creator(remoteObj, wants);
144 if (helper == nullptr) {
145 HILOG_ERROR("creator return nullptr.");
146 return false;
147 }
148 setuid(UID_DEFAULT);
149 return true;
150 }
151
GetDownloadUri()152 static tuple<shared_ptr<FileAccessHelper>, Uri> GetDownloadUri()
153 {
154 shared_ptr<FileAccessHelper> helper = GetFileAccessHelper();
155 if (helper == nullptr) {
156 HILOG_ERROR("GetFileAccessHelper return nullptr.");
157 return {nullptr, Uri("")};
158 }
159 vector<RootInfo> info;
160 int result = helper->GetRoots(info);
161 if (result != OHOS::FileAccessFwk::ERR_OK) {
162 HILOG_ERROR("GetRoots failed. ret : %{public}d", result);
163 return {helper, Uri("")};
164 }
165 Uri rootUri("");
166 if (info.size() > OHOS::FileAccessFwk::ERR_OK) {
167 rootUri = Uri(info[0].uri + "/file");
168 }
169 bool isExist = false;
170 Uri downloadUri(rootUri.ToString() + "/Download");
171 result = helper->Access(downloadUri, isExist);
172 if (result <= OHOS::FileAccessFwk::ERR_OK) {
173 HILOG_ERROR("Access failed. ret : %{public}d", result);
174 return {helper, Uri("")};
175 }
176 if (isExist) {
177 return {helper, downloadUri};
178 }
179 downloadUri = Uri("");
180 result = helper->Mkdir(rootUri, "Download", downloadUri);
181 if (result <= OHOS::FileAccessFwk::ERR_OK) {
182 HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
183 return {helper, Uri("")};
184 }
185 return {helper, downloadUri};
186 }
187
AccessFuzzTest(const uint8_t * data,size_t size)188 bool AccessFuzzTest(const uint8_t* data, size_t size)
189 {
190 shared_ptr<FileAccessHelper> helper;
191 Uri downloadUri;
192
193 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
194 return false;
195 }
196 Uri uri(downloadUri.ToString() + "/" + std::string(reinterpret_cast<const char*>(data), size));
197 bool isExist = false;
198 int result = helper->Access(uri, isExist);
199 if (isExist != true || result != OHOS::FileAccessFwk::ERR_OK) {
200 HILOG_ERROR("Access failed. ret : %{public}d", result);
201 return false;
202 }
203 return true;
204 }
205
OpenFileFuzzTest(const uint8_t * data,size_t size)206 bool OpenFileFuzzTest(const uint8_t* data, size_t size)
207 {
208 shared_ptr<FileAccessHelper> helper;
209 Uri downloadUri;
210
211 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
212 return false;
213 }
214 Uri uri(downloadUri.ToString() + "/" + std::string(reinterpret_cast<const char*>(data), size));
215 int fd = -1;
216 int result = helper->OpenFile(uri, WRITE_READ, fd);
217 if (result != OHOS::FileAccessFwk::ERR_OK) {
218 HILOG_ERROR("OpenFile failed. ret : %{public}d", result);
219 return false;
220 }
221 close(fd);
222 return true;
223 }
224
CreateFileFuzzTest(const uint8_t * data,size_t size)225 bool CreateFileFuzzTest(const uint8_t* data, size_t size)
226 {
227 shared_ptr<FileAccessHelper> helper;
228 Uri downloadUri;
229
230 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
231 return false;
232 }
233 Uri newFileUri("");
234 int result = helper->CreateFile(downloadUri, std::string(reinterpret_cast<const char*>(data), size), newFileUri);
235 if (result != OHOS::FileAccessFwk::ERR_OK) {
236 HILOG_ERROR("CreateFile failed. ret : %{public}d", result);
237 return false;
238 }
239 result = helper->Delete(newFileUri);
240 if (result != OHOS::FileAccessFwk::ERR_OK) {
241 HILOG_ERROR("Delete failed. ret : %{public}d", result);
242 return false;
243 }
244 return true;
245 }
246
MkdirFuzzTest(const uint8_t * data,size_t size)247 bool MkdirFuzzTest(const uint8_t* data, size_t size)
248 {
249 shared_ptr<FileAccessHelper> helper;
250 Uri downloadUri;
251
252 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
253 return false;
254 }
255 Uri newDirUri("");
256 int result = helper->Mkdir(downloadUri, std::string(reinterpret_cast<const char*>(data), size), newDirUri);
257 if (result != OHOS::FileAccessFwk::ERR_OK) {
258 HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
259 return false;
260 }
261 result = helper->Delete(newDirUri);
262 if (result != OHOS::FileAccessFwk::ERR_OK) {
263 HILOG_ERROR("Delete failed. ret : %{public}d", result);
264 return false;
265 }
266 return true;
267 }
268
DeleteFuzzTest(const uint8_t * data,size_t size)269 bool DeleteFuzzTest(const uint8_t* data, size_t size)
270 {
271 shared_ptr<FileAccessHelper> helper;
272 Uri downloadUri;
273
274 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
275 return false;
276 }
277 Uri uri(downloadUri.ToString() + "/" + std::string(reinterpret_cast<const char*>(data), size));
278 int result = helper->Delete(uri);
279 if (result != OHOS::FileAccessFwk::ERR_OK) {
280 HILOG_ERROR("Delete failed. ret : %{public}d", result);
281 return false;
282 }
283 return true;
284 }
285
MoveFuzzTest(const uint8_t * data,size_t size)286 bool MoveFuzzTest(const uint8_t* data, size_t size)
287 {
288 shared_ptr<FileAccessHelper> helper;
289 Uri downloadUri;
290
291 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
292 return false;
293 }
294 Uri newDirUriTest1("");
295 Uri newDirUriTest2("");
296 int result = helper->Mkdir(downloadUri, "test1", newDirUriTest1);
297 if (result != OHOS::FileAccessFwk::ERR_OK) {
298 HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
299 return false;
300 }
301 result = helper->Mkdir(downloadUri, "test2", newDirUriTest2);
302 if (result != OHOS::FileAccessFwk::ERR_OK) {
303 HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
304 return false;
305 }
306 Uri testUri("");
307 result = helper->CreateFile(newDirUriTest1, std::string(reinterpret_cast<const char*>(data), size), testUri);
308 if (result != OHOS::FileAccessFwk::ERR_OK) {
309 HILOG_ERROR("CreateFile failed. ret : %{public}d", result);
310 return false;
311 }
312 Uri testUri2("");
313 result = helper->Move(testUri, newDirUriTest2, testUri2);
314 if (result != OHOS::FileAccessFwk::ERR_OK) {
315 HILOG_ERROR("Move failed. ret : %{public}d", result);
316 return false;
317 }
318 result = helper->Delete(newDirUriTest1);
319 if (result != OHOS::FileAccessFwk::ERR_OK) {
320 HILOG_ERROR("Delete failed. ret : %{public}d", result);
321 return false;
322 }
323 result = helper->Delete(newDirUriTest2);
324 if (result != OHOS::FileAccessFwk::ERR_OK) {
325 HILOG_ERROR("Delete failed. ret : %{public}d", result);
326 return false;
327 }
328 return true;
329 }
330
RenameFuzzTest(const uint8_t * data,size_t size)331 bool RenameFuzzTest(const uint8_t* data, size_t size)
332 {
333 shared_ptr<FileAccessHelper> helper;
334 Uri downloadUri;
335
336 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
337 return false;
338 }
339 Uri newDirUriTest("");
340 int result = helper->Mkdir(downloadUri, "test", newDirUriTest);
341 if (result != OHOS::FileAccessFwk::ERR_OK) {
342 HILOG_ERROR("Mkdir failed. ret : %{public}d", result);
343 return false;
344 }
345 Uri renameUri("");
346 result = helper->Rename(newDirUriTest, std::string(reinterpret_cast<const char*>(data), size), renameUri);
347 if (result != OHOS::FileAccessFwk::ERR_OK) {
348 HILOG_ERROR("Rename failed. ret : %{public}d", result);
349 return false;
350 }
351 result = helper->Delete(renameUri);
352 if (result != OHOS::FileAccessFwk::ERR_OK) {
353 HILOG_ERROR("Delete failed. ret : %{public}d", result);
354 return false;
355 }
356 return true;
357 }
358
ListFileFuzzTest(const uint8_t * data,size_t size)359 bool ListFileFuzzTest(const uint8_t* data, size_t size)
360 {
361 shared_ptr<FileAccessHelper> helper;
362 Uri downloadUri;
363
364 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
365 return false;
366 }
367 FileInfo fileInfo;
368 fileInfo.uri = downloadUri.ToString() + "/" + std::string(reinterpret_cast<const char*>(data), size);
369 int64_t offset = 0;
370 int64_t maxCount = 1000;
371 std::vector<FileInfo> fileInfoVec;
372 FileFilter filter;
373 int result = helper->ListFile(fileInfo, offset, maxCount, filter, fileInfoVec);
374 if (result != OHOS::FileAccessFwk::ERR_OK) {
375 HILOG_ERROR("ListFile failed. ret : %{public}d", result);
376 return false;
377 }
378 return true;
379 }
380
ScanFileFuzzTest(const uint8_t * data,size_t size)381 bool ScanFileFuzzTest(const uint8_t* data, size_t size)
382 {
383 shared_ptr<FileAccessHelper> helper;
384 Uri downloadUri;
385 if (!CheckDataAndGetDownloadUri(data, size, helper, downloadUri)) {
386 return false;
387 }
388 FileInfo fileInfo;
389 fileInfo.uri = downloadUri.ToString() + "/" + std::string(reinterpret_cast<const char*>(data), size);
390 int64_t offset = 0;
391 int64_t maxCount = 1000;
392 std::vector<FileInfo> fileInfoVec;
393 FileFilter filter;
394 int result = helper->ScanFile(fileInfo, offset, maxCount, filter, fileInfoVec);
395 if (result != OHOS::FileAccessFwk::ERR_OK) {
396 HILOG_ERROR("ScanFile failed. ret : %{public}d", result);
397 return false;
398 }
399 return true;
400 }
401
402 }
403
404 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)405 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
406 {
407 /* Run your code on data */
408 OHOS::CreatorFuzzTest(data, size);
409 OHOS::AccessFuzzTest(data, size);
410 OHOS::OpenFileFuzzTest(data, size);
411 OHOS::MkdirFuzzTest(data, size);
412 OHOS::CreateFileFuzzTest(data, size);
413 OHOS::DeleteFuzzTest(data, size);
414 OHOS::MoveFuzzTest(data, size);
415 OHOS::RenameFuzzTest(data, size);
416 OHOS::ListFileFuzzTest(data, size);
417 OHOS::ScanFileFuzzTest(data, size);
418 return 0;
419 }