diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn index bf1321dd96f9ee16352d366111fc18f88c578083..9abe65a24547d7aaf3935384f4b394d7264719c8 100644 --- a/test/fuzztest/BUILD.gn +++ b/test/fuzztest/BUILD.gn @@ -30,6 +30,7 @@ group("user_file_service_fuzz_test") { "externalfileaccessscanfile_fuzzer:ExternalFileAccessScanFileFuzzTest", "fileaccessextbaseproxy_fuzzer:FileAccessExtBaseProxyFuzzTest", "fileaccessextconnection_fuzzer:FileAccessExtConnectionFuzzTest", + "fileaccessservicebaseproxy_fuzzer:FileAccessServiceBaseProxyFuzzTest", "fileinfosharedmemory_fuzzer:FileInfoSharedMemoryFuzzTest", "useraccesscommonutils_fuzzer:UserAccessCommonUtilsFuzzTest", ] diff --git a/test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn b/test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn index 50675fadd6cb53cfd61e79a9228ccf5f3bdd14df..a5d06f8fb44f14a586d76452085efd6cc4a988b3 100644 --- a/test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn +++ b/test/fuzztest/fileaccessextbaseproxy_fuzzer/BUILD.gn @@ -55,6 +55,7 @@ ohos_fuzztest("FileAccessExtBaseProxyFuzzTest") { "hitrace:hitrace_meter", "ipc:ipc_core", "safwk:system_ability_fwk", + "samgr:samgr_proxy", ] defines = [ "private=public" ] diff --git a/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp b/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp index 795e9dcab3ea2e3ca665877c90d25d2d9f1b7fb5..fa52bac213c28c6087a77f845c870ac22d719dc3 100644 --- a/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp +++ b/test/fuzztest/fileaccessextbaseproxy_fuzzer/fileaccessextbaseproxy_fuzzer.cpp @@ -323,6 +323,49 @@ bool MoveFileFuzzTest(sptr proxy, const uint8_t *data, size_ proxy->MoveFile(sourceFile, targetParent, fileName, newFile); return true; } + +bool UrieFuzzTest(const uint8_t *data, size_t size) +{ + int len = size / 2; + Urie uri(string(reinterpret_cast(data), len)); + Urie other(string(reinterpret_cast(data + len), len)); + + uri.uriString_ = string(reinterpret_cast(data), len); + uri.GetScheme(); + uri.GetSchemeSpecificPart(); + uri.GetAuthority(); + uri.GetHost(); + uri.GetPort(); + uri.GetUserInfo(); + uri.GetQuery(); + uri.GetPath(); + uri.GetFragment(); + uri.IsHierarchical(); + uri.IsAbsolute(); + uri.IsRelative(); + uri.ToString(); + uri.CheckScheme(); + uri.ParseScheme(); + uri.ParseSsp(); + uri.ParseAuthority(); + uri.ParseUserInfo(); + uri.ParseHost(); + uri.ParsePort(); + uri.ParsePath(); + uri.ParsePath(NOT_FOUND); + uri.ParseQuery(); + uri.ParseFragment(); + uri.FindSchemeSeparator(); + uri.FindFragmentSeparator(); + uri.Equals(other); + uri.CompareTo(other); + vector segments; + uri.GetPathSegments(segments); + Parcel parcel; + uri.Marshalling(parcel); + uri.Unmarshalling(parcel); + return (uri == other); +} } // namespace OHOS /* Fuzzer entry point */ @@ -330,7 +373,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { auto helper = OHOS::GetFileAccessHelper(); if (helper == nullptr) { - printf("GetFileAccessHelper return nullptr."); + printf("helper is nullptr."); return false; } auto proxy = helper->GetProxyByBundleName(OHOS::EXTERNAL_BNUDLE_NAME); @@ -358,5 +401,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) OHOS::MoveItemFuzzTest(proxy, data, size); OHOS::MoveFileFuzzTest(proxy, data, size); + OHOS::UrieFuzzTest(data, size); return 0; } diff --git a/test/fuzztest/fileaccessservicebaseproxy_fuzzer/BUILD.gn b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d71705ab9a022025d91a34e1dcd0bc1318f95112 --- /dev/null +++ b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/BUILD.gn @@ -0,0 +1,67 @@ +# 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") + +##############################fuzztest########################################## +ohos_fuzztest("FileAccessServiceBaseProxyFuzzTest") { + module_out_path = "user_file_service/user_file_service" + fuzz_config_file = + "${user_file_service_path}/test/fuzztest/fileaccessservicebaseproxy_fuzzer" + + include_dirs = [ + "${user_file_service_path}/interfaces/inner_api/file_access/include", + "${user_file_service_path}/utils", + ] + + sources = [ "fileaccessservicebaseproxy_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", + "samgr:samgr_proxy", + ] + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + defines = [ "private=public" ] +} diff --git a/test/fuzztest/fileaccessservicebaseproxy_fuzzer/corpus/init b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..7ade8a0faafeaedba7241e7d4a97b8e1f9691932 --- /dev/null +++ b/test/fuzztest/fileaccessservicebaseproxy_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/fileaccessservicebaseproxy_fuzzer/fileaccessservicebaseproxy_fuzzer.cpp b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/fileaccessservicebaseproxy_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..962422561cf14766cd8d33cc476159bf02e60744 --- /dev/null +++ b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/fileaccessservicebaseproxy_fuzzer.cpp @@ -0,0 +1,198 @@ +/* + * 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 "fileaccessservicebaseproxy_fuzzer.h" + +#include + +#include "app_file_access_ext_connection.h" +#include "file_access_observer_stub.h" +#include "file_access_service_client.h" + +#include "accesstoken_kit.h" +#include "file_access_helper.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; +} + +class TestObserver : public FileAccessObserverStub { +public: + TestObserver() {}; + virtual ~TestObserver() = default; + int OnChange(const NotifyMessage ¬ifyMessage) override; +}; + +int TestObserver::OnChange(const NotifyMessage ¬ifyMessage) +{ + return 1; +} + +bool OnChangeFuzzTest(sptr proxy, const uint8_t* data, size_t size) +{ + if (data == nullptr || size < sizeof(NotifyType)) { + return true; + } + + int pos = 0; + NotifyType notifyType = TypeCast(data, &pos); + Uri uri(string(reinterpret_cast(data + pos), size - pos)); + proxy->OnChange(uri, notifyType); + return true; +} + +bool ConnectFileExtAbilityFuzzTest(sptr proxy, const uint8_t* data, size_t size) +{ + int len = size / 2; + string bundleName(reinterpret_cast(data), len); + string infoName(reinterpret_cast(data + len), len); + AAFwk::Want want; + want.SetElementName(bundleName, infoName); + + auto helper = GetFileAccessHelper(); + if (helper == nullptr) { + printf("helper is nullptr."); + return 0; + } + auto connectInfo = helper->GetConnectInfo("com.ohos.UserFile.ExternalFileManager"); + if (connectInfo == nullptr) { + printf("connectInfo is nullptr"); + return 0; + } + auto fileAccessExtConnection = connectInfo->fileAccessExtConnection; + if (fileAccessExtConnection == nullptr) { + printf("fileAccessExtConnection is nullptr"); + } + proxy->ConnectFileExtAbility(want, connectInfo->fileAccessExtConnection); + proxy->DisConnectFileExtAbility(connectInfo->fileAccessExtConnection); + return true; +} + +bool UnregisterNotifyNoObserverFuzzTest(sptr proxy, const uint8_t* data, size_t size) +{ + if (data == nullptr || size < sizeof(bool)) { + return true; + } + + int pos = sizeof(bool); + Uri uri(string(reinterpret_cast(data + pos), size - pos)); + AAFwk::Want want; + want.SetElementName(EXTERNAL_BNUDLE_NAME, "FileExtensionAbility"); + std::shared_ptr info = std::make_shared(want, g_fah->token_); + proxy->UnregisterNotifyNoObserver(uri, *info); + return true; +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + auto proxy = OHOS::FileAccessFwk::FileAccessServiceClient::GetInstance(); + if (proxy == nullptr) { + printf("service proxy is nullptr"); + return 0; + } + /* Run your code on data */ + OHOS::OnChangeFuzzTest(proxy, data, size); + OHOS::ConnectFileExtAbilityFuzzTest(proxy, data, size); + OHOS::UnregisterNotifyNoObserverFuzzTest(proxy, data, size); + return 0; +} diff --git a/test/fuzztest/fileaccessservicebaseproxy_fuzzer/fileaccessservicebaseproxy_fuzzer.h b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/fileaccessservicebaseproxy_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..a38e99fa68ae5445dc8ad894642e4640d6c543cb --- /dev/null +++ b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/fileaccessservicebaseproxy_fuzzer.h @@ -0,0 +1,23 @@ +/* + * 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_SERVICE_BASE_PROXY_FUZZER_FUZZER_H +#define FILE_ACCESS_SERVICE_BASE_PROXY_FUZZER_FUZZER_H + +#define FUZZ_PROJECT_NAME "file_access_service_base_proxy_fuzzer" + +#endif // FILE_ACCESS_SERVICE_BASE_PROXY_FUZZER_FUZZER_H + diff --git a/test/fuzztest/fileaccessservicebaseproxy_fuzzer/project.xml b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..66e1dcac475475fb101b6f8670ec699e6e9696aa --- /dev/null +++ b/test/fuzztest/fileaccessservicebaseproxy_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + +