• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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