From 96e1ad2031fe7a46e0921073bfbec60d82f37d16 Mon Sep 17 00:00:00 2001 From: wangpggg Date: Wed, 28 May 2025 14:01:26 +0800 Subject: [PATCH] add fuzz Signed-off-by: wangpeng --- .../inner_api/file_access/src/uri_ext.cpp | 2 +- test/fuzztest/BUILD.gn | 1 + .../fileaccessextbaseproxy_fuzzer/BUILD.gn | 61 +++ .../fileaccessextbaseproxy_fuzzer/corpus/init | 16 + .../fileaccessextbaseproxy_fuzzer.cpp | 362 ++++++++++++++++++ .../fileaccessextbaseproxy_fuzzer.h | 21 + .../fileaccessextbaseproxy_fuzzer/project.xml | 25 ++ 7 files changed, 487 insertions(+), 1 deletion(-) create mode 100644 test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn create mode 100644 test/fuzztest/fileaccessextbaseproxy_fuzzer/corpus/init create mode 100644 test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp create mode 100644 test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.h create mode 100644 test/fuzztest/fileaccessextbaseproxy_fuzzer/project.xml diff --git a/interfaces/inner_api/file_access/src/uri_ext.cpp b/interfaces/inner_api/file_access/src/uri_ext.cpp index d155d4b3..f9994f23 100644 --- a/interfaces/inner_api/file_access/src/uri_ext.cpp +++ b/interfaces/inner_api/file_access/src/uri_ext.cpp @@ -57,7 +57,7 @@ Urie::Urie(const std::string& uriString) : OHOS::Uri(uriString) if (!CheckScheme()) { uriString_ = EMPTY; - std::cerr << "URI Scheme wrong" << std::endl; // 简单的错误输出,可替换为合适的日志记录方式 + HILOG_IMPL(LOG_CORE, LOG_DEBUG, 0xD001305, "URIe", "URI Scheme wrong"); } } diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn index c43b0ec3..bf1321dd 100644 --- a/test/fuzztest/BUILD.gn +++ b/test/fuzztest/BUILD.gn @@ -28,6 +28,7 @@ group("user_file_service_fuzz_test") { "externalfileaccessopenfile_fuzzer:ExternalFileAccessOpenFileFuzzTest", "externalfileaccessrename_fuzzer:ExternalFileAccessRenameFuzzTest", "externalfileaccessscanfile_fuzzer:ExternalFileAccessScanFileFuzzTest", + "fileaccessextbaseproxy_fuzzer:FileAccessExtBaseProxyFuzzTest", "fileaccessextconnection_fuzzer:FileAccessExtConnectionFuzzTest", "fileinfosharedmemory_fuzzer:FileInfoSharedMemoryFuzzTest", "useraccesscommonutils_fuzzer:UserAccessCommonUtilsFuzzTest", diff --git a/test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn b/test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn new file mode 100644 index 00000000..50675fad --- /dev/null +++ b/test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn @@ -0,0 +1,61 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#####################hydra-fuzz################### +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/filemanagement/user_file_service/filemanagement_aafwk.gni") +ohos_fuzztest("FileAccessExtBaseProxyFuzzTest") { + module_out_path = "user_file_service/user_file_service" + fuzz_config_file = + "${user_file_service_path}/test/fuzztest/fileaccessextbaseproxy_fuzzer" + include_dirs = [ + "${user_file_service_path}/interfaces/inner_api/file_access/include", + "${user_file_service_path}/utils", + ] + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + sources = [ "fileaccessextbaseproxy_fuzzer.cpp" ] + + deps = [ + "${user_file_service_path}/interfaces/inner_api/file_access:file_access_ext_base_include", + "${user_file_service_path}/interfaces/inner_api/file_access:file_access_extension_ability_kit", + "${user_file_service_path}/services:file_access_service", + "${user_file_service_path}/services:file_access_service_base_include", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "ability_runtime:app_manager", + "ability_runtime:runtime", + "ability_runtime:wantagent_innerkits", + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "safwk:system_ability_fwk", + ] + + defines = [ "private=public" ] +} diff --git a/test/fuzztest/fileaccessextbaseproxy_fuzzer/corpus/init b/test/fuzztest/fileaccessextbaseproxy_fuzzer/corpus/init new file mode 100644 index 00000000..7ade8a0f --- /dev/null +++ b/test/fuzztest/fileaccessextbaseproxy_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +FUZZ \ No newline at end of file diff --git a/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp b/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp new file mode 100644 index 00000000..795e9dca --- /dev/null +++ b/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "fileaccessextbaseproxy_fuzzer.h" + +#include +#include + +#include "accesstoken_kit.h" +#include "file_access_helper.h" +#include "file_access_ext_base_proxy.h" +#include "file_info_shared_memory.h" +#include "iservice_registry.h" +#include "token_setproc.h" +#include "nativetoken_kit.h" + +namespace OHOS { +using namespace std; +using namespace FileAccessFwk; + +const int ABILITY_ID = 5003; +shared_ptr g_fah = nullptr; +const int UID_TRANSFORM_TMP = 20000000; +const int UID_DEFAULT = 0; + +template +T TypeCast(const uint8_t *data, int *pos = nullptr) +{ + if (pos) { + *pos += sizeof(T); + } + return *(reinterpret_cast(data)); +} + +void SetNativeToken() +{ + uint64_t tokenId; + const char *perms[] = { + "ohos.permission.FILE_ACCESS_MANAGER", + "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", + "ohos.permission.CONNECT_FILE_ACCESS_EXTENSION" + }; + NativeTokenInfoParams infoInstance = { + .dcapsNum = 0, + .permsNum = 3, + .aclsNum = 0, + .dcaps = nullptr, + .perms = perms, + .acls = nullptr, + .aplStr = "system_core", + }; + + infoInstance.processName = "SetUpTestCase"; + tokenId = GetAccessTokenId(&infoInstance); + const uint64_t systemAppMask = (static_cast(1) << 32); + tokenId |= systemAppMask; + SetSelfTokenID(tokenId); + OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo(); +} + +shared_ptr GetFileAccessHelper() +{ + if (g_fah != nullptr) { + return g_fah; + } + SetNativeToken(); + auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (saManager == nullptr) { + return nullptr; + } + auto remoteObj = saManager->GetSystemAbility(ABILITY_ID); + AAFwk::Want want; + vector wantVec; + setuid(UID_TRANSFORM_TMP); + int ret = FileAccessHelper::GetRegisteredFileAccessExtAbilityInfo(wantVec); + if (ret != OHOS::FileAccessFwk::ERR_OK) { + printf("GetRegisteredFileAccessExtAbilityInfo failed."); + return nullptr; + } + bool sus = false; + for (size_t i = 0; i < wantVec.size(); i++) { + auto element = wantVec[i].GetElement(); + if (element.GetBundleName() == "com.ohos.UserFile.ExternalFileManager" && + element.GetAbilityName() == "FileExtensionAbility") { + want = wantVec[i]; + sus = true; + break; + } + } + if (!sus) { + printf("not found bundleName."); + return nullptr; + } + vector wants {want}; + g_fah = FileAccessHelper::Creator(remoteObj, wants); + setuid(UID_DEFAULT); + if (g_fah == nullptr) { + printf("creator fileAccessHelper return nullptr."); + return nullptr; + } + return g_fah; +} + +bool OpenFileFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(int32_t) + sizeof(int)) { + return true; + } + + int pos = 0; + int32_t flags = TypeCast(data, &pos); + int fd = TypeCast(data + pos, &pos); + Urie uri(string(reinterpret_cast(data + pos), size - sizeof(int32_t) - sizeof(int))); + proxy->OpenFile(uri, flags, fd); + return true; +} + +bool CreateFileFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + int len = size / 3; + Urie parent(string(reinterpret_cast(data), len)); + string displayName(string(reinterpret_cast(data + len), len)); + Urie newFile(string(reinterpret_cast(data + len + len), len)); + proxy->CreateFile(parent, displayName, newFile); + return true; +} + +bool MkdirFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + int len = size / 3; + Urie parent(string(reinterpret_cast(data), len)); + string displayName(string(reinterpret_cast(data + len), len)); + Urie newFile(string(reinterpret_cast(data + len + len), len)); + proxy->Mkdir(parent, displayName, newFile); + return true; +} + +bool DeleteFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + Urie sourceFile(string(reinterpret_cast(data), size)); + proxy->Delete(sourceFile); + return true; +} + +bool MoveFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + int len = size / 3; + Urie sourceFile(string(reinterpret_cast(data), len)); + string targetParent(string(reinterpret_cast(data + len), len)); + Urie newFile(string(reinterpret_cast(data + len + len), len)); + proxy->Move(sourceFile, targetParent, newFile); + return true; +} + +bool CopyFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(bool)) { + return true; + } + + vector copyResult; + int32_t retCode = 0; + int pos = 0; + bool force = TypeCast(data, &pos); + int len = (size - pos) / 2; + Urie sourceUri(string(reinterpret_cast(data + pos), len)); + Urie destUri(string(reinterpret_cast(data + pos + len), len)); + + proxy->Copy(sourceUri, destUri, copyResult, retCode, force); + return true; +} + +bool CopyFileFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + int len = size / 3; + Urie sourceUri(string(reinterpret_cast(data), len)); + Urie destUri(string(reinterpret_cast(data + len), len)); + string fileName(string(reinterpret_cast(data + len + len), len)); + Urie newFileUri; + proxy->CopyFile(sourceUri, destUri, fileName, newFileUri); + return true; +} + +bool RenameFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + int len = size / 2; + Urie sourceFile(string(reinterpret_cast(data), len)); + string displayName(string(reinterpret_cast(data + len), len)); + Urie newFile; + proxy->Rename(sourceFile, displayName, newFile); + return true; +} + +bool ListFileFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(int64_t)) { + return true; + } + + int pos = 0; + int64_t offset = TypeCast(data, &pos); + + FileInfo fileInfo; + fileInfo.uri = std::string(reinterpret_cast(data + pos), size - pos); + SharedMemoryInfo memInfo; + int result = SharedMemoryOperation::CreateSharedMemory("FileInfo List", DEFAULT_CAPACITY_200KB, memInfo); + if (result != OHOS::FileAccessFwk::ERR_OK) { + printf("CreateSharedMemory failed. ret : %d", result); + return false; + } + FileFilter filter; + proxy->ListFile(fileInfo, offset, filter, memInfo); + SharedMemoryOperation::DestroySharedMemory(memInfo); + return true; +} + +bool ScanFileFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(int64_t) + sizeof(int64_t)) { + return true; + } + + int pos = 0; + int64_t offset = TypeCast(data, &pos); + int64_t maxCount = TypeCast(data + pos, &pos); + + FileInfo fileInfo; + fileInfo.uri = std::string(reinterpret_cast(data + pos), size - pos); + std::vector fileInfoVec; + FileFilter filter; + proxy->ScanFile(fileInfo, offset, maxCount, filter, fileInfoVec); + return true; +} + +bool QueryFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + int len = size / 4; + Urie uri(string(reinterpret_cast(data), len)); + vector columns { + string(reinterpret_cast(data + len), len), + string(reinterpret_cast(data + len + len), len), + string(reinterpret_cast(data + len + len + len), len) + }; + vector results; + proxy->Query(uri, columns, results); + return true; +} + +bool GetFileInfoFromUriFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + Urie selectFile(string(reinterpret_cast(data), size)); + FileInfo fileInfo; + proxy->GetFileInfoFromUri(selectFile, fileInfo); + return true; +} + +bool GetRootsFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + (void)data; + vector rootInfoVec; + proxy->GetRoots(rootInfoVec); + return true; +} + +bool AccessFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + Urie uri(string(reinterpret_cast(data), size)); + bool isExist = false; + proxy->Access(uri, isExist); + return true; +} + +bool StartWatcherFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + Urie uri(string(reinterpret_cast(data), size)); + proxy->StartWatcher(uri); + return true; +} + +bool StopWatcherFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + Urie uri(string(reinterpret_cast(data), size)); + proxy->StopWatcher(uri); + return true; +} + +bool MoveItemFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(bool)) { + return true; + } + + vector moveResult; + int32_t retCode = 0; + int pos = 0; + bool force = TypeCast(data, &pos); + int len = (size - pos) / 2; + Urie sourceFile(string(reinterpret_cast(data + pos), len)); + Urie targetParent(string(reinterpret_cast(data + pos + len), len)); + + proxy->MoveItem(sourceFile, targetParent, moveResult, retCode, force); + return true; +} + +bool MoveFileFuzzTest(sptr proxy, const uint8_t *data, size_t size) +{ + int len = size / 3; + Urie sourceFile(string(reinterpret_cast(data), len)); + Urie targetParent(string(reinterpret_cast(data + len), len)); + string fileName(string(reinterpret_cast(data + len + len), len)); + Urie newFile; + proxy->MoveFile(sourceFile, targetParent, fileName, newFile); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + auto helper = OHOS::GetFileAccessHelper(); + if (helper == nullptr) { + printf("GetFileAccessHelper return nullptr."); + return false; + } + auto proxy = helper->GetProxyByBundleName(OHOS::EXTERNAL_BNUDLE_NAME); + if (proxy == nullptr) { + printf("get proxy failed."); + return 0; + } + + OHOS::OpenFileFuzzTest(proxy, data, size); + OHOS::CreateFileFuzzTest(proxy, data, size); + OHOS::MkdirFuzzTest(proxy, data, size); + OHOS::DeleteFuzzTest(proxy, data, size); + OHOS::MoveFuzzTest(proxy, data, size); + OHOS::CopyFuzzTest(proxy, data, size); + OHOS::CopyFileFuzzTest(proxy, data, size); + OHOS::RenameFuzzTest(proxy, data, size); + OHOS::ListFileFuzzTest(proxy, data, size); + OHOS::ScanFileFuzzTest(proxy, data, size); + OHOS::QueryFuzzTest(proxy, data, size); + OHOS::GetFileInfoFromUriFuzzTest(proxy, data, size); + OHOS::GetRootsFuzzTest(proxy, data, size); + OHOS::AccessFuzzTest(proxy, data, size); + OHOS::StartWatcherFuzzTest(proxy, data, size); + OHOS::StopWatcherFuzzTest(proxy, data, size); + OHOS::MoveItemFuzzTest(proxy, data, size); + OHOS::MoveFileFuzzTest(proxy, data, size); + + return 0; +} diff --git a/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.h b/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.h new file mode 100644 index 00000000..5be5cb28 --- /dev/null +++ b/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_ACCESS_EXTBASEPROXY_FUZZER_H +#define FILE_ACCESS_EXTBASEPROXY_FUZZER_H + +#define FUZZ_PROJECT_NAME "fileaccessextbaseproxy_fuzzer" + +#endif \ No newline at end of file diff --git a/test/fuzztest/fileaccessextbaseproxy_fuzzer/project.xml b/test/fuzztest/fileaccessextbaseproxy_fuzzer/project.xml new file mode 100644 index 00000000..8cd95817 --- /dev/null +++ b/test/fuzztest/fileaccessextbaseproxy_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + -- Gitee