diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn index 1c4fd3c4f567601e4feae5e657def3faaddece0f..d585d42d764eac76e74054243a802c5e154516ac 100644 --- a/test/fuzztest/BUILD.gn +++ b/test/fuzztest/BUILD.gn @@ -64,5 +64,6 @@ group("fuzztest") { "ipc/native/src/mock/acquirehandle_fuzzer:AcquireHandleFuzzTest", "dbinder/dbinder_service/src/dbinderservicenew_fuzzer:DBinderServiceNewFuzzTest", "dbinder/dbinder_service/src/socket/dbinderremotelistener_fuzzer:DBinderRemoteListenerFuzzTest", + "dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer:DBinderServiceStubNewFuzzTest", ] } diff --git a/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/BUILD.gn b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d5756506e991f51115b47228401e431c751105b2 --- /dev/null +++ b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/BUILD.gn @@ -0,0 +1,40 @@ +# 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") +SUBSYSTEM_DIR = "//foundation/communication/ipc" + +##############################fuzztest########################################## +ohos_fuzztest("DBinderServiceStubNewFuzzTest") { + module_out_path = "ipc/ipc" + fuzz_config_file = "../dbinderservicestubnew_fuzzer" + include_dirs = [ + "$SUBSYSTEM_DIR/interfaces/innerkits/ipc_core/include", + ] + defines = [ + "private = public", + "protected = public", + ] + sources = [ "dbinderservicestubnew_fuzzer.cpp" ] + #deps = [ "../../../../../../test:ipc_single_test_static" ] + external_deps = [ + "c_utils:utils", + "googletest:gmock", + "googletest:gtest", + "hilog:libhilog", + "ipc:libdbinder", + "ipc:ipc_core", + ] +} diff --git a/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/corpus/init b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..7ade8a0faafeaedba7241e7d4a97b8e1f9691932 --- /dev/null +++ b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_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/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/dbinderservicestubnew_fuzzer.cpp b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/dbinderservicestubnew_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58490d66d73ba54bb207ffb5d28f95565420f7f1 --- /dev/null +++ b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/dbinderservicestubnew_fuzzer.cpp @@ -0,0 +1,250 @@ +/* + * 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 "dbinderservicestubnew_fuzzer.h" + +#include +#include + +#include +#include +#include +#include "dbinder_service.h" +#include "dbinder_service_stub.h" +#include "string_ex.h" +#include "ipc_skeleton.h" + +using namespace testing; +using namespace testing::ext; + + +namespace OHOS { + +static constexpr uint32_t FIRST_CALL = 0x00000001; +static constexpr uint32_t LAST_CALL = 0x5fffffff; +static constexpr uint32_t DBINDER_HANDLE_BASE = 100000 * 6872; + +class DBinderServiceStubInterface { +public: + DBinderServiceStubInterface() {}; + virtual ~DBinderServiceStubInterface() {}; + + virtual pid_t GetCallingPid() = 0; + virtual pid_t GetCallingUid() = 0; + virtual bool AddDeathRecipient(const sptr&) = 0; + virtual sptr GetInstance() = 0; + virtual bool AttachCallbackProxy(sptr, DBinderServiceStub*) = 0; +}; + +class DBinderServiceStubInterfaceMock : public DBinderServiceStubInterface { +public: + DBinderServiceStubInterfaceMock(); + ~DBinderServiceStubInterfaceMock() override; + + MOCK_METHOD0(GetCallingPid, pid_t()); + MOCK_METHOD0(GetCallingUid, pid_t()); + MOCK_METHOD1(AddDeathRecipient, bool(const sptr&)); + MOCK_METHOD0(GetInstance, sptr()); + MOCK_METHOD2(AttachCallbackProxy, bool(sptr, DBinderServiceStub*)); +}; + +static void *g_interface = nullptr; + +DBinderServiceStubInterfaceMock::DBinderServiceStubInterfaceMock() +{ + g_interface = reinterpret_cast(this); +} + +DBinderServiceStubInterfaceMock::~DBinderServiceStubInterfaceMock() +{ + g_interface = nullptr; +} + +static DBinderServiceStubInterfaceMock *GetDBinderServiceStubInterfaceMock() +{ + return reinterpret_cast(g_interface); +} + +extern "C" { + pid_t IPCSkeleton::GetCallingPid() + { + if (g_interface == nullptr) { + return -1; + } + + return GetDBinderServiceStubInterfaceMock()->GetCallingPid(); + } + + pid_t IPCSkeleton::GetCallingUid() + { + if (g_interface == nullptr) { + return -1; + } + + return GetDBinderServiceStubInterfaceMock()->GetCallingUid(); + } + + bool IPCObjectProxy::AddDeathRecipient(const sptr &recipient) + { + if (g_interface == nullptr) { + return false; + } + + return GetDBinderServiceStubInterfaceMock()->AddDeathRecipient(recipient); + } + + sptr DBinderService::GetInstance() + { + if (g_interface == nullptr) { + return nullptr; + } + + return GetDBinderServiceStubInterfaceMock()->GetInstance(); + } + + bool DBinderService::AttachCallbackProxy(sptr object, DBinderServiceStub *dbStub) + { + if (g_interface == nullptr) { + return false; + } + + return GetDBinderServiceStubInterfaceMock()->AttachCallbackProxy(object, dbStub); + } +} + +void ProcessProtoTest(FuzzedDataProvider &provider) +{ + const std::string service = provider.ConsumeRandomLengthString(); + const std::string device = provider.ConsumeRandomLengthString(); + binder_uintptr_t object = provider.ConsumeIntegral(); + DBinderServiceStub dBinderServiceStub(Str8ToStr16(service), device, object); + uint32_t code = provider.ConsumeIntegralInRange(FIRST_CALL_TRANSACTION, LAST_CALL_TRANSACTION); + MessageParcel data; + MessageParcel reply; + MessageOption option; + dBinderServiceStub.ProcessProto(code, data, reply, option); + + binder_uintptr_t key = provider.ConsumeIntegral(); + sptr dBinderService = DBinderService::GetInstance(); + if (dBinderService == nullptr) { + return; + } + std::shared_ptr sessionInfo = std::make_shared(); + if (sessionInfo == nullptr) { + return; + } + dBinderService->AttachSessionObject(sessionInfo, key); + + NiceMock mock; + EXPECT_CALL(mock, GetCallingPid).WillRepeatedly(testing::Return(-1)); + EXPECT_CALL(mock, GetCallingUid).WillRepeatedly(testing::Return(-1)); + dBinderServiceStub.ProcessProto(code, data, reply, option); + + //预期localBusName不为空 + EXPECT_CALL(mock, GetCallingPid).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(mock, GetCallingUid).WillRepeatedly(testing::Return(1)); + dBinderServiceStub.ProcessProto(code, data, reply, option); +} + +void OnRemoteRequestTest(FuzzedDataProvider &provider) +{ + const std::string service = provider.ConsumeRandomLengthString(); + const std::string device = provider.ConsumeRandomLengthString(); + binder_uintptr_t object = provider.ConsumeIntegral(); + DBinderServiceStub dBinderServiceStub(Str8ToStr16(service), device, object); + MessageParcel data; + MessageParcel reply; + MessageOption option; + int32_t code = provider.ConsumeIntegralInRange(FIRST_CALL, LAST_CALL); + dBinderServiceStub.OnRemoteRequest(code, data, reply, option); +} + +void ProcessDeathRecipientTest(FuzzedDataProvider &provider) +{ + const std::string service = provider.ConsumeRandomLengthString(); + const std::string device = provider.ConsumeRandomLengthString(); + binder_uintptr_t object = provider.ConsumeIntegral(); + DBinderServiceStub dBinderServiceStub(Str8ToStr16(service), device, object); + MessageParcel data; + MessageParcel reply; + MessageOption option; + int32_t processType = provider.ConsumeIntegralInRange(IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT, IRemoteObject::DeathRecipient::TEST_DEVICE_DEATH_RECIPIENT); + data.WriteInt32(processType); + dBinderServiceStub.ProcessDeathRecipient(data); +} + +void AddDbinderDeathRecipientTest1(FuzzedDataProvider &provider) +{ + const std::string service = provider.ConsumeRandomLengthString(); + const std::string device = provider.ConsumeRandomLengthString(); + binder_uintptr_t object = provider.ConsumeIntegral(); + DBinderServiceStub dBinderServiceStub(Str8ToStr16(service), device, object); + + std::string descriptor = provider.ConsumeRandomLengthString(); + uint32_t handle = provider.ConsumeIntegralInRange(0, DBINDER_HANDLE_BASE); + sptr callbackProxy = new (std::nothrow) IPCObjectProxy(handle, Str8ToStr16(descriptor)); + if (callbackProxy == nullptr) { + return; + } + //callbackProxy->SetObjectDied(true); + MessageParcel data; + data.WriteRemoteObject(callbackProxy); + NiceMock mock; + EXPECT_CALL(mock, AddDeathRecipient).WillRepeatedly(testing::Return(false)); + dBinderServiceStub.AddDbinderDeathRecipient(data); + + EXPECT_CALL(mock, AddDeathRecipient).WillRepeatedly(testing::Return(true)); + EXPECT_CALL(mock, GetInstance).WillRepeatedly(testing::Return(nullptr)); + dBinderServiceStub.AddDbinderDeathRecipient(data); +} + +void AddDbinderDeathRecipientTest2(FuzzedDataProvider &provider) +{ + const std::string service = provider.ConsumeRandomLengthString(); + const std::string device = provider.ConsumeRandomLengthString(); + binder_uintptr_t object = provider.ConsumeIntegral(); + DBinderServiceStub dBinderServiceStub(Str8ToStr16(service), device, object); + + std::string descriptor = provider.ConsumeRandomLengthString(); + uint32_t handle = provider.ConsumeIntegralInRange(0, DBINDER_HANDLE_BASE); + sptr callbackProxy = new (std::nothrow) IPCObjectProxy(handle, Str8ToStr16(descriptor)); + if (callbackProxy == nullptr) { + return; + } + MessageParcel data; + data.WriteRemoteObject(callbackProxy); + NiceMock mock; + EXPECT_CALL(mock, AttachCallbackProxy).WillRepeatedly(testing::Return(false)); + dBinderServiceStub.AddDbinderDeathRecipient(data); +} + +void FuzzTest(FuzzedDataProvider &provider) +{ + ProcessProtoTest(provider); + OnRemoteRequestTest(provider); + ProcessDeathRecipientTest(provider); + AddDbinderDeathRecipientTest1(provider); + AddDbinderDeathRecipientTest2(provider); +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + /* Run your code on data */ + FuzzedDataProvider provider(data, size); + OHOS::FuzzTest(provider); + return 0; +} diff --git a/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/dbinderservicestubnew_fuzzer.h b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/dbinderservicestubnew_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..78ef8bb587c3c45c88108d126550dc25a5210740 --- /dev/null +++ b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/dbinderservicestubnew_fuzzer.h @@ -0,0 +1,27 @@ +/* + * 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 DBINDERSERVICESTUBNEW_FUZZER_H +#define DBINDERSERVICESTUBNEW_FUZZER_H + +#include +#include +#include +#include +#include +#include + +#define FUZZ_PROJECT_NAME "dbinderservicestubnew_fuzzer" + +#endif \ No newline at end of file diff --git a/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/project.xml b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..66e1dcac475475fb101b6f8670ec699e6e9696aa --- /dev/null +++ b/test/fuzztest/dbinder/dbinder_service/src/dbinderservicestubnew_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + +