1 /*
2 * Copyright (c) 2025 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 #include "fileaccessextbaseproxy_fuzzer.h"
16
17 #include <string>
18 #include <vector>
19
20 #include "accesstoken_kit.h"
21 #include "file_access_helper.h"
22 #include "file_access_ext_base_proxy.h"
23 #include "file_info_shared_memory.h"
24 #include "iservice_registry.h"
25 #include "token_setproc.h"
26 #include "nativetoken_kit.h"
27
28 namespace OHOS {
29 using namespace std;
30 using namespace FileAccessFwk;
31
32 const int ABILITY_ID = 5003;
33 shared_ptr<FileAccessHelper> g_fah = nullptr;
34 const int UID_TRANSFORM_TMP = 20000000;
35 const int UID_DEFAULT = 0;
36
37 template <class T>
TypeCast(const uint8_t * data,int * pos=nullptr)38 T TypeCast(const uint8_t *data, int *pos = nullptr)
39 {
40 if (pos) {
41 *pos += sizeof(T);
42 }
43 return *(reinterpret_cast<const T *>(data));
44 }
45
SetNativeToken()46 void SetNativeToken()
47 {
48 uint64_t tokenId;
49 const char *perms[] = {
50 "ohos.permission.FILE_ACCESS_MANAGER",
51 "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED",
52 "ohos.permission.CONNECT_FILE_ACCESS_EXTENSION"
53 };
54 NativeTokenInfoParams infoInstance = {
55 .dcapsNum = 0,
56 .permsNum = 3,
57 .aclsNum = 0,
58 .dcaps = nullptr,
59 .perms = perms,
60 .acls = nullptr,
61 .aplStr = "system_core",
62 };
63
64 infoInstance.processName = "SetUpTestCase";
65 tokenId = GetAccessTokenId(&infoInstance);
66 const uint64_t systemAppMask = (static_cast<uint64_t>(1) << 32);
67 tokenId |= systemAppMask;
68 SetSelfTokenID(tokenId);
69 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
70 }
71
GetFileAccessHelper()72 shared_ptr<FileAccessHelper> GetFileAccessHelper()
73 {
74 if (g_fah != nullptr) {
75 return g_fah;
76 }
77 SetNativeToken();
78 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
79 if (saManager == nullptr) {
80 return nullptr;
81 }
82 auto remoteObj = saManager->GetSystemAbility(ABILITY_ID);
83 AAFwk::Want want;
84 vector<AAFwk::Want> wantVec;
85 setuid(UID_TRANSFORM_TMP);
86 int ret = FileAccessHelper::GetRegisteredFileAccessExtAbilityInfo(wantVec);
87 if (ret != OHOS::FileAccessFwk::ERR_OK) {
88 printf("GetRegisteredFileAccessExtAbilityInfo failed.");
89 return nullptr;
90 }
91 bool sus = false;
92 for (size_t i = 0; i < wantVec.size(); i++) {
93 auto element = wantVec[i].GetElement();
94 if (element.GetBundleName() == "com.ohos.UserFile.ExternalFileManager" &&
95 element.GetAbilityName() == "FileExtensionAbility") {
96 want = wantVec[i];
97 sus = true;
98 break;
99 }
100 }
101 if (!sus) {
102 printf("not found bundleName.");
103 return nullptr;
104 }
105 vector<AAFwk::Want> wants {want};
106 g_fah = FileAccessHelper::Creator(remoteObj, wants);
107 setuid(UID_DEFAULT);
108 if (g_fah == nullptr) {
109 printf("creator fileAccessHelper return nullptr.");
110 return nullptr;
111 }
112 return g_fah;
113 }
114
OpenFileFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)115 bool OpenFileFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
116 {
117 if (data == nullptr || size < sizeof(int32_t) + sizeof(int)) {
118 return true;
119 }
120
121 int pos = 0;
122 int32_t flags = TypeCast<int32_t>(data, &pos);
123 int fd = TypeCast<int>(data + pos, &pos);
124 Urie uri(string(reinterpret_cast<const char *>(data + pos), size - sizeof(int32_t) - sizeof(int)));
125 proxy->OpenFile(uri, flags, fd);
126 return true;
127 }
128
CreateFileFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)129 bool CreateFileFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
130 {
131 int len = size / 3;
132 Urie parent(string(reinterpret_cast<const char *>(data), len));
133 string displayName(string(reinterpret_cast<const char *>(data + len), len));
134 Urie newFile(string(reinterpret_cast<const char *>(data + len + len), len));
135 proxy->CreateFile(parent, displayName, newFile);
136 return true;
137 }
138
MkdirFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)139 bool MkdirFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
140 {
141 int len = size / 3;
142 Urie parent(string(reinterpret_cast<const char *>(data), len));
143 string displayName(string(reinterpret_cast<const char *>(data + len), len));
144 Urie newFile(string(reinterpret_cast<const char *>(data + len + len), len));
145 proxy->Mkdir(parent, displayName, newFile);
146 return true;
147 }
148
DeleteFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)149 bool DeleteFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
150 {
151 Urie sourceFile(string(reinterpret_cast<const char *>(data), size));
152 proxy->Delete(sourceFile);
153 return true;
154 }
155
MoveFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)156 bool MoveFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
157 {
158 int len = size / 3;
159 Urie sourceFile(string(reinterpret_cast<const char *>(data), len));
160 string targetParent(string(reinterpret_cast<const char *>(data + len), len));
161 Urie newFile(string(reinterpret_cast<const char *>(data + len + len), len));
162 proxy->Move(sourceFile, targetParent, newFile);
163 return true;
164 }
165
CopyFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)166 bool CopyFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
167 {
168 if (data == nullptr || size < sizeof(bool)) {
169 return true;
170 }
171
172 vector<Result> copyResult;
173 int32_t retCode = 0;
174 int pos = 0;
175 bool force = TypeCast<bool>(data, &pos);
176 int len = (size - pos) / 2;
177 Urie sourceUri(string(reinterpret_cast<const char *>(data + pos), len));
178 Urie destUri(string(reinterpret_cast<const char *>(data + pos + len), len));
179
180 proxy->Copy(sourceUri, destUri, copyResult, retCode, force);
181 return true;
182 }
183
CopyFileFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)184 bool CopyFileFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
185 {
186 int len = size / 3;
187 Urie sourceUri(string(reinterpret_cast<const char *>(data), len));
188 Urie destUri(string(reinterpret_cast<const char *>(data + len), len));
189 string fileName(string(reinterpret_cast<const char *>(data + len + len), len));
190 Urie newFileUri;
191 proxy->CopyFile(sourceUri, destUri, fileName, newFileUri);
192 return true;
193 }
194
RenameFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)195 bool RenameFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
196 {
197 int len = size / 2;
198 Urie sourceFile(string(reinterpret_cast<const char *>(data), len));
199 string displayName(string(reinterpret_cast<const char *>(data + len), len));
200 Urie newFile;
201 proxy->Rename(sourceFile, displayName, newFile);
202 return true;
203 }
204
ListFileFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)205 bool ListFileFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
206 {
207 if (data == nullptr || size < sizeof(int64_t)) {
208 return true;
209 }
210
211 int pos = 0;
212 int64_t offset = TypeCast<int64_t>(data, &pos);
213
214 FileInfo fileInfo;
215 fileInfo.uri = std::string(reinterpret_cast<const char*>(data + pos), size - pos);
216 SharedMemoryInfo memInfo;
217 int result = SharedMemoryOperation::CreateSharedMemory("FileInfo List", DEFAULT_CAPACITY_200KB, memInfo);
218 if (result != OHOS::FileAccessFwk::ERR_OK) {
219 printf("CreateSharedMemory failed. ret : %d", result);
220 return false;
221 }
222 FileFilter filter;
223 proxy->ListFile(fileInfo, offset, filter, memInfo);
224 SharedMemoryOperation::DestroySharedMemory(memInfo);
225 return true;
226 }
227
ScanFileFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)228 bool ScanFileFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
229 {
230 if (data == nullptr || size < sizeof(int64_t) + sizeof(int64_t)) {
231 return true;
232 }
233
234 int pos = 0;
235 int64_t offset = TypeCast<int64_t>(data, &pos);
236 int64_t maxCount = TypeCast<int64_t>(data + pos, &pos);
237
238 FileInfo fileInfo;
239 fileInfo.uri = std::string(reinterpret_cast<const char*>(data + pos), size - pos);
240 std::vector<FileInfo> fileInfoVec;
241 FileFilter filter;
242 proxy->ScanFile(fileInfo, offset, maxCount, filter, fileInfoVec);
243 return true;
244 }
245
QueryFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)246 bool QueryFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
247 {
248 int len = size / 4;
249 Urie uri(string(reinterpret_cast<const char *>(data), len));
250 vector<string> columns {
251 string(reinterpret_cast<const char *>(data + len), len),
252 string(reinterpret_cast<const char *>(data + len + len), len),
253 string(reinterpret_cast<const char *>(data + len + len + len), len)
254 };
255 vector<string> results;
256 proxy->Query(uri, columns, results);
257 return true;
258 }
259
GetFileInfoFromUriFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)260 bool GetFileInfoFromUriFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
261 {
262 Urie selectFile(string(reinterpret_cast<const char *>(data), size));
263 FileInfo fileInfo;
264 proxy->GetFileInfoFromUri(selectFile, fileInfo);
265 return true;
266 }
267
GetRootsFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)268 bool GetRootsFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
269 {
270 (void)data;
271 vector<RootInfo> rootInfoVec;
272 proxy->GetRoots(rootInfoVec);
273 return true;
274 }
275
AccessFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)276 bool AccessFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
277 {
278 Urie uri(string(reinterpret_cast<const char *>(data), size));
279 bool isExist = false;
280 proxy->Access(uri, isExist);
281 return true;
282 }
283
StartWatcherFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)284 bool StartWatcherFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
285 {
286 Urie uri(string(reinterpret_cast<const char *>(data), size));
287 proxy->StartWatcher(uri);
288 return true;
289 }
290
StopWatcherFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)291 bool StopWatcherFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
292 {
293 Urie uri(string(reinterpret_cast<const char *>(data), size));
294 proxy->StopWatcher(uri);
295 return true;
296 }
297
MoveItemFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)298 bool MoveItemFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
299 {
300 if (data == nullptr || size < sizeof(bool)) {
301 return true;
302 }
303
304 vector<Result> moveResult;
305 int32_t retCode = 0;
306 int pos = 0;
307 bool force = TypeCast<bool>(data, &pos);
308 int len = (size - pos) / 2;
309 Urie sourceFile(string(reinterpret_cast<const char *>(data + pos), len));
310 Urie targetParent(string(reinterpret_cast<const char *>(data + pos + len), len));
311
312 proxy->MoveItem(sourceFile, targetParent, moveResult, retCode, force);
313 return true;
314 }
315
MoveFileFuzzTest(sptr<IFileAccessExtBase> proxy,const uint8_t * data,size_t size)316 bool MoveFileFuzzTest(sptr<IFileAccessExtBase> proxy, const uint8_t *data, size_t size)
317 {
318 int len = size / 3;
319 Urie sourceFile(string(reinterpret_cast<const char *>(data), len));
320 Urie targetParent(string(reinterpret_cast<const char *>(data + len), len));
321 string fileName(string(reinterpret_cast<const char *>(data + len + len), len));
322 Urie newFile;
323 proxy->MoveFile(sourceFile, targetParent, fileName, newFile);
324 return true;
325 }
326
UrieFuzzTest(const uint8_t * data,size_t size)327 bool UrieFuzzTest(const uint8_t *data, size_t size)
328 {
329 int len = size / 2;
330 Urie uri(string(reinterpret_cast<const char *>(data), len));
331 Urie other(string(reinterpret_cast<const char *>(data + len), len));
332
333 uri.uriString_ = string(reinterpret_cast<const char *>(data), len);
334 uri.GetScheme();
335 uri.GetSchemeSpecificPart();
336 uri.GetAuthority();
337 uri.GetHost();
338 uri.GetPort();
339 uri.GetUserInfo();
340 uri.GetQuery();
341 uri.GetPath();
342 uri.GetFragment();
343 uri.IsHierarchical();
344 uri.IsAbsolute();
345 uri.IsRelative();
346 uri.ToString();
347 uri.CheckScheme();
348 uri.ParseScheme();
349 uri.ParseSsp();
350 uri.ParseAuthority();
351 uri.ParseUserInfo();
352 uri.ParseHost();
353 uri.ParsePort();
354 uri.ParsePath();
355 uri.ParsePath(NOT_FOUND);
356 uri.ParseQuery();
357 uri.ParseFragment();
358 uri.FindSchemeSeparator();
359 uri.FindFragmentSeparator();
360 uri.Equals(other);
361 uri.CompareTo(other);
362 vector<std::string> segments;
363 uri.GetPathSegments(segments);
364 Parcel parcel;
365 uri.Marshalling(parcel);
366 uri.Unmarshalling(parcel);
367 return (uri == other);
368 }
369 } // namespace OHOS
370
371 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)372 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
373 {
374 auto helper = OHOS::GetFileAccessHelper();
375 if (helper == nullptr) {
376 printf("helper is nullptr.");
377 return false;
378 }
379 auto proxy = helper->GetProxyByBundleName(OHOS::EXTERNAL_BNUDLE_NAME);
380 if (proxy == nullptr) {
381 printf("get proxy failed.");
382 return 0;
383 }
384
385 OHOS::OpenFileFuzzTest(proxy, data, size);
386 OHOS::CreateFileFuzzTest(proxy, data, size);
387 OHOS::MkdirFuzzTest(proxy, data, size);
388 OHOS::DeleteFuzzTest(proxy, data, size);
389 OHOS::MoveFuzzTest(proxy, data, size);
390 OHOS::CopyFuzzTest(proxy, data, size);
391 OHOS::CopyFileFuzzTest(proxy, data, size);
392 OHOS::RenameFuzzTest(proxy, data, size);
393 OHOS::ListFileFuzzTest(proxy, data, size);
394 OHOS::ScanFileFuzzTest(proxy, data, size);
395 OHOS::QueryFuzzTest(proxy, data, size);
396 OHOS::GetFileInfoFromUriFuzzTest(proxy, data, size);
397 OHOS::GetRootsFuzzTest(proxy, data, size);
398 OHOS::AccessFuzzTest(proxy, data, size);
399 OHOS::StartWatcherFuzzTest(proxy, data, size);
400 OHOS::StopWatcherFuzzTest(proxy, data, size);
401 OHOS::MoveItemFuzzTest(proxy, data, size);
402 OHOS::MoveFileFuzzTest(proxy, data, size);
403
404 OHOS::UrieFuzzTest(data, size);
405 return 0;
406 }
407