diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn index b2c8058c9e70cfbec3532786c5390f4c948695bc..92b375f4218c88a39344b089ee4e10f7fcd56508 100644 --- a/test/fuzztest/BUILD.gn +++ b/test/fuzztest/BUILD.gn @@ -15,6 +15,7 @@ group("fuzztest") { testonly = true deps = [ "interfaces/innerkits/ipc_core/messageparcel:messageparcelfuzz", + "interfaces/innerkits/ipc_core/messageparcelmock:messageparcelmockfuzztest", "ipc/native/src/core/adddeathrecipient_fuzzer:AddDeathRecipientFuzzTest", "ipc/native/src/core/bind_fuzzer:BindFuzzTest", "ipc/native/src/core/binderinvoker:binderinvokerfuzz", diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/BUILD.gn b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4633f5116cb223b790f89dc220690f94bbe881a3 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/BUILD.gn @@ -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. + +group("messageparcelmockfuzztest") { + testonly = true + deps = [ + "messageparcelmock001_fuzzer:MessageParcelMock001FuzzTest", + "messageparcelmock002_fuzzer:MessageParcelMock002FuzzTest", + "messageparcelmock003_fuzzer:MessageParcelMock003FuzzTest", + ] +} diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/include/messageparcelmock_fuzzer.h b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/include/messageparcelmock_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..ddf8c93a62b5c9a1e271d72c4afc0c55f5fd799f --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/include/messageparcelmock_fuzzer.h @@ -0,0 +1,24 @@ +/* + * 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 MESSAGEPARCEL_MOCK_FUZZER_H +#define MESSAGEPARCEL_MOCK_FUZZER_H + +#include +#include + +#define FUZZ_PROJECT_NAME "messageparcelmock_fuzzer" + +#endif // MESSAGEPARCEL_MOCK_FUZZER_H \ No newline at end of file diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/BUILD.gn b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..da1d9b22728eafc18bf6982212dde4ab5e774451 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/BUILD.gn @@ -0,0 +1,46 @@ +# 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("MessageParcelMock001FuzzTest") { + module_out_path = "ipc/ipc" + fuzz_config_file = "../messageparcelmock001_fuzzer" + + include_dirs = [ + "../include", + "$SUBSYSTEM_DIR/utils/include", + "$SUBSYSTEM_DIR/ipc/native/src/core/framework/source/", + ] + + sources = [ "messageparcelmock001_fuzzer.cpp" ] + + deps = [ "$SUBSYSTEM_DIR/interfaces/innerkits/ipc_single:ipc_single_test" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "googletest:gmock", + "googletest:gtest", + ] + + defines = [ + "private = public", + "protected = public", + ] + resource_config_file = "$SUBSYSTEM_DIR/test/resource/ipc/ohos_test.xml" +} diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/corpus/init b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..7ade8a0faafeaedba7241e7d4a97b8e1f9691932 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_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/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/messageparcelmock001_fuzzer.cpp b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/messageparcelmock001_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afa36b7adf003a9b5cc217c91fd9c34e04524753 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/messageparcelmock001_fuzzer.cpp @@ -0,0 +1,224 @@ +/* + * 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 "messageparcelmock_fuzzer.h" + +#include +#include +#include +#include +#include "ipc_object_stub.h" +#include "ipc_file_descriptor.h" +#include "iremote_object.h" +#include "ipc_process_skeleton.h" +#include "process_skeleton.h" +#include "message_parcel.h" +#include "sys_binder.h" +#include "string_ex.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +const static size_t MAX_STRING_PARAM_LEN = 100; + +class MessageParcelInstence { +public: + MessageParcelInstence() {}; + virtual ~MessageParcelInstence() {}; + + virtual IPCProcessSkeleton *GetCurrent() = 0; + virtual bool WriteInt32(int32_t value) = 0; + virtual bool WriteBuffer(const void *data, size_t size) = 0; + virtual bool WriteObjectOffset(binder_size_t offset) = 0; + virtual bool RewindWrite(size_t position) = 0; + virtual bool WriteFileDescriptor(int fd) = 0; +}; + +class MessageParcelInstenceMock : public MessageParcelInstence { +public: + MessageParcelInstenceMock(); + ~MessageParcelInstenceMock() override; + + MOCK_METHOD0(GetCurrent, IPCProcessSkeleton *()); + MOCK_METHOD1(WriteInt32, bool(int32_t value)); + MOCK_METHOD2(WriteBuffer, bool(const void *data, size_t size)); + MOCK_METHOD1(WriteObjectOffset, bool(binder_size_t offset)); + MOCK_METHOD1(RewindWrite, bool(size_t position)); + MOCK_METHOD1(WriteFileDescriptor, bool(int fd)); +}; + +static void *g_interface = nullptr; + +MessageParcelInstenceMock::MessageParcelInstenceMock() +{ + g_interface = reinterpret_cast(this); +} + +MessageParcelInstenceMock::~MessageParcelInstenceMock() +{ + g_interface = nullptr; +} + +static MessageParcelInstenceMock *GetMessageParcelInstenceMock() +{ + return reinterpret_cast(g_interface); +} + +extern "C" { + IPCProcessSkeleton *IPCProcessSkeleton::GetCurrent() + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return nullptr; + } + return interface->GetCurrent(); + } + + bool Parcel::WriteInt32(int32_t value) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->WriteInt32(value); + } + + bool Parcel::WriteBuffer(const void *data, size_t size) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->WriteBuffer(data, size); + } + + bool Parcel::WriteObjectOffset(binder_size_t offset) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->WriteObjectOffset(offset); + } + + bool Parcel::RewindWrite(size_t newPosition) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->RewindWrite(newPosition); + } + + bool MessageParcel::WriteFileDescriptor(int fd) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->WriteFileDescriptor(fd); + } +} + +void WriteDBinderProxyFuzzTest(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + uint32_t handle = provider.ConsumeIntegral(); + sptr object = new (std::nothrow) IPCObjectProxy(handle); + if (object == nullptr) { + return; + } + uint64_t stubIndex = provider.ConsumeIntegral(); + NiceMock mock; + EXPECT_CALL(mock, GetCurrent).WillOnce(Return(nullptr)); + parcel.WriteDBinderProxy(object, handle, stubIndex); +} + +void UpdateDBinderDataOffsetFuzzTest(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + binder_buffer_object bufferObject; + bufferObject.parent = provider.ConsumeIntegral(); + bufferObject.parent_offset = provider.ConsumeIntegral(); + bufferObject.hdr.type = BINDER_TYPE_PTR; + bufferObject.flags = BINDER_BUFFER_FLAG_HAS_DBINDER; + bufferObject.length = sizeof(dbinder_negotiation_data); + parcel.WriteBuffer(&bufferObject, sizeof(binder_buffer_object)); + NiceMock mock; + EXPECT_CALL(mock, WriteObjectOffset).WillOnce(Return(false)); + parcel.UpdateDBinderDataOffset((reinterpret_cast(&bufferObject) - parcel.GetData())); +} + +void WriteInterfaceTokenFuzzTest(FuzzedDataProvider &provider) +{ + std::string interfaceToken = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + std::u16string interfaceToken16 = Str8ToStr16(interfaceToken); + NiceMock mock; + EXPECT_CALL(mock, WriteInt32).WillOnce(Return(false)); + MessageParcel parcel; + parcel.WriteInterfaceToken(interfaceToken16); + + int strictModePolicy = 0x100; + constexpr int workSource = 0; + EXPECT_CALL(mock, WriteInt32(strictModePolicy)).WillRepeatedly(testing::Return(true)); + EXPECT_CALL(mock, WriteInt32(workSource)).WillRepeatedly(testing::Return(false)); + EXPECT_CALL(mock, RewindWrite).WillOnce(Return(false)); + parcel.WriteInterfaceToken(interfaceToken16); +} + +void WriteRawDataFuzzTest001(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + std::string rawData = provider.ConsumeRandomLengthString(MessageParcel::MAX_RAWDATA_SIZE); + size_t bytesSize = rawData.size(); + if (bytesSize <= MessageParcel::MIN_RAWDATA_SIZE || bytesSize > MessageParcel::MAX_RAWDATA_SIZE) { + return; + } + NiceMock mock; + EXPECT_CALL(mock, WriteInt32).WillOnce(Return(false)); + parcel.WriteRawData(static_cast(rawData.c_str()), bytesSize); + + EXPECT_CALL(mock, WriteInt32).WillRepeatedly(testing::Return(true)); + EXPECT_CALL(mock, WriteFileDescriptor).WillOnce(Return(false)); + parcel.WriteRawData(static_cast(rawData.c_str()), bytesSize); +} + +void WriteRawDataFuzzTest002(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + std::string rawData = provider.ConsumeRandomLengthString(MessageParcel::MAX_RAWDATA_SIZE); + if (rawData.size() <= MessageParcel::MIN_RAWDATA_SIZE) { + return; + } + NiceMock mock; + EXPECT_CALL(mock, WriteInt32).WillRepeatedly(testing::Return(true)); + EXPECT_CALL(mock, WriteFileDescriptor).WillOnce(Return(true)); + parcel.WriteRawData(static_cast(rawData.c_str()), rawData.size()); +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + /* Run your code on data */ + FuzzedDataProvider provider(data, size); + OHOS::WriteDBinderProxyFuzzTest(provider); + OHOS::UpdateDBinderDataOffsetFuzzTest(provider); + OHOS::WriteInterfaceTokenFuzzTest(provider); + OHOS::WriteRawDataFuzzTest001(provider); + OHOS::WriteRawDataFuzzTest002(provider); + return 0; +} diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/project.xml b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..226522bd2ad3eaf2db4f710f1924d82d2912c235 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock001_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 10000 + + 300 + + 4096 + + diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/BUILD.gn b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..bd26fb4bba8884de2cc180cf7b4fd9898656880a --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/BUILD.gn @@ -0,0 +1,46 @@ +# 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("MessageParcelMock002FuzzTest") { + module_out_path = "ipc/ipc" + fuzz_config_file = "../messageparcelmock002_fuzzer" + + include_dirs = [ + "../include", + "$SUBSYSTEM_DIR/utils/include", + "$SUBSYSTEM_DIR/ipc/native/src/core/framework/source/", + ] + + sources = [ "messageparcelmock002_fuzzer.cpp" ] + + deps = [ "$SUBSYSTEM_DIR/interfaces/innerkits/ipc_single:ipc_single_test" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "googletest:gmock", + "googletest:gtest", + ] + + defines = [ + "private = public", + "protected = public", + ] + resource_config_file = "$SUBSYSTEM_DIR/test/resource/ipc/ohos_test.xml" +} diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/corpus/init b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..7ade8a0faafeaedba7241e7d4a97b8e1f9691932 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_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/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/messageparcelmock002_fuzzer.cpp b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/messageparcelmock002_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7857e16c9bfbd5e360581588f74e9c0a504e8ed5 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/messageparcelmock002_fuzzer.cpp @@ -0,0 +1,262 @@ +/* + * 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 "messageparcelmock_fuzzer.h" +#include "ashmem.h" +#include "ipc_object_stub.h" +#include "ipc_file_descriptor.h" +#include "iremote_object.h" +#include "ipc_process_skeleton.h" +#include "process_skeleton.h" +#include "message_parcel.h" +#include "sys_binder.h" +#include +#include +#include +#include + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +const static size_t MAX_STRING_PARAM_LEN = 100; + +class MessageParcelInstence { +public: + MessageParcelInstence() {}; + virtual ~MessageParcelInstence() {}; + + virtual bool WriteInt32(int32_t value) = 0; + virtual bool WriteBuffer(const void *data, size_t size) = 0; + virtual int32_t ReadInt32() = 0; + virtual int AshmemCreate(const char *name, size_t size) = 0; + virtual int AshmemSetProt(int fd, int prot); + virtual int ReadFileDescriptor() = 0; + virtual int AshmemGetSize(int fd) = 0; + virtual int GetAshmemFd() = 0; +}; + +class MessageParcelInstenceMock : public MessageParcelInstence { +public: + MessageParcelInstenceMock(); + ~MessageParcelInstenceMock() override; + + MOCK_METHOD1(WriteInt32, bool(int32_t value)); + MOCK_METHOD2(WriteBuffer, bool(const void *data, size_t size)); + MOCK_METHOD0(ReadInt32, int32_t()); + MOCK_METHOD2(AshmemCreate, int(const char *name, size_t size)); + MOCK_METHOD2(AshmemSetProt, int(int fd, int prot)); + MOCK_METHOD0(ReadFileDescriptor, int()); + MOCK_METHOD1(AshmemGetSize, int(int fd)); + MOCK_METHOD0(GetAshmemFd, int()); +}; + +static void *g_interface = nullptr; + +MessageParcelInstenceMock::MessageParcelInstenceMock() +{ + g_interface = reinterpret_cast(this); +} + +MessageParcelInstenceMock::~MessageParcelInstenceMock() +{ + g_interface = nullptr; +} + +static MessageParcelInstenceMock *GetMessageParcelInstenceMock() +{ + return reinterpret_cast(g_interface); +} + +extern "C" { + bool Parcel::WriteInt32(int32_t value) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->WriteInt32(value); + } + + bool Parcel::WriteBuffer(const void *data, size_t size) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->WriteBuffer(data, size); + } + + int32_t Parcel::ReadInt32() + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->ReadInt32(); + } + + int MessageParcel::ReadFileDescriptor() + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->ReadFileDescriptor(); + } +} + +int AshmemCreate(const char *name, size_t size) +{ + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return -1; + } + return interface->AshmemCreate(name, size); +} + +int AshmemSetProt(int fd, int prot) +{ + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return -1; + } + return interface->AshmemSetProt(fd, prot); +} + +int AshmemGetSize(int fd) +{ + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return -1; + } + return interface->AshmemGetSize(fd); +} + +int GetAshmemFd() +{ + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return -1; + } + return interface->GetAshmemFd(); +} + +void WriteRawDataFuzzTest(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + std::string rawData = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + size_t bytesSize = rawData.size(); + if (bytesSize <= MessageParcel::MIN_RAWDATA_SIZE || bytesSize > MessageParcel::MAX_RAWDATA_SIZE) { + return; + } + NiceMock mock; + EXPECT_CALL(mock, WriteInt32).WillRepeatedly(testing::Return(true)); + EXPECT_CALL(mock, AshmemCreate).WillOnce(Return(-1)); + parcel.WriteRawData(static_cast(rawData.c_str()), bytesSize); + + EXPECT_CALL(mock, AshmemCreate).WillOnce(Return(1)); + EXPECT_CALL(mock, AshmemSetProt).WillOnce(Return(-1)); + parcel.WriteRawData(static_cast(rawData.c_str()), bytesSize); + + EXPECT_CALL(mock, AshmemCreate).WillOnce(Return(1)); + EXPECT_CALL(mock, AshmemSetProt).WillOnce(Return(1)); + parcel.WriteRawData(static_cast(rawData.c_str()), bytesSize); +} + +void ReadRawDataInnerFuzzTest001(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + size_t size = provider.ConsumeIntegral(); + parcel.ReadRawDataInner(size); + + NiceMock mock; + EXPECT_CALL(mock, ReadFileDescriptor).WillOnce(Return(-1)); + parcel.ReadRawDataInner(size); + + EXPECT_CALL(mock, ReadFileDescriptor).WillOnce(Return(1)); + EXPECT_CALL(mock, AshmemGetSize).WillOnce(Return(0)); + parcel.ReadRawDataInner(size); + + EXPECT_CALL(mock, ReadFileDescriptor).WillOnce(Return(1)); + EXPECT_CALL(mock, AshmemGetSize).WillOnce(Return(size)); + parcel.ReadRawDataInner(size); +} + +void ReadRawDataInnerFuzzTest002(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + size_t size = provider.ConsumeIntegral(); + size_t rawDatasize = provider.ConsumeIntegral(); + std::shared_ptr rawData = std::make_shared(); + parcel.RestoreRawData(rawData, rawDatasize); + NiceMock mock; + EXPECT_CALL(mock, ReadFileDescriptor).WillOnce(Return(-1)); + parcel.ReadRawDataInner(size); + + EXPECT_CALL(mock, ReadFileDescriptor).WillOnce(Return(1)); + parcel.ReadRawDataInner(rawDatasize); + + EXPECT_CALL(mock, ReadFileDescriptor).WillOnce(Return(1)); + parcel.ReadRawDataInner(size); +} + +void ReadRawDataFuzzTest(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + std::string data = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + size_t size = provider.ConsumeIntegral(); + size_t bytesSize = + provider.ConsumeIntegralInRange(MessageParcel::MIN_RAWDATA_SIZE + 1, MessageParcel::MAX_RAWDATA_SIZE); + parcel.WriteBuffer(data.data(), data.size()); + NiceMock mock; + EXPECT_CALL(mock, ReadInt32).WillOnce(Return(1)); + parcel.ReadRawData(size); + + EXPECT_CALL(mock, ReadInt32).WillOnce(Return(bytesSize)); + parcel.ReadRawData(bytesSize); +} + +void WriteAshmemFuzzTest(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + std::string data = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + sptr ashmem = Ashmem::CreateAshmem(data.c_str(), data.size()); + if (ashmem == nullptr) { + return; + } + NiceMock mock; + EXPECT_CALL(mock, GetAshmemFd).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(mock, AshmemGetSize).WillRepeatedly(testing::Return(0)); + parcel.WriteAshmem(ashmem); + + EXPECT_CALL(mock, AshmemGetSize).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(mock, WriteInt32).WillRepeatedly(testing::Return(false)); + parcel.WriteAshmem(ashmem); +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + /* Run your code on data */ + FuzzedDataProvider provider(data, size); + OHOS::WriteRawDataFuzzTest(provider); + OHOS::ReadRawDataInnerFuzzTest001(provider); + OHOS::ReadRawDataInnerFuzzTest002(provider); + OHOS::ReadRawDataFuzzTest(provider); + OHOS::WriteAshmemFuzzTest(provider); + return 0; +} diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/project.xml b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..226522bd2ad3eaf2db4f710f1924d82d2912c235 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock002_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 10000 + + 300 + + 4096 + + diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/BUILD.gn b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..bc6b723ec9dd9388c13c768801033e5ec13ae929 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/BUILD.gn @@ -0,0 +1,46 @@ +# 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("MessageParcelMock003FuzzTest") { + module_out_path = "ipc/ipc" + fuzz_config_file = "../messageparcelmock003_fuzzer" + + include_dirs = [ + "../include", + "$SUBSYSTEM_DIR/utils/include", + "$SUBSYSTEM_DIR/ipc/native/src/core/framework/source/", + ] + + sources = [ "messageparcelmock003_fuzzer.cpp" ] + + deps = [ "$SUBSYSTEM_DIR/interfaces/innerkits/ipc_single:ipc_single_test" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "googletest:gmock", + "googletest:gtest", + ] + + defines = [ + "private = public", + "protected = public", + ] + resource_config_file = "$SUBSYSTEM_DIR/test/resource/ipc/ohos_test.xml" +} diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/corpus/init b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..7ade8a0faafeaedba7241e7d4a97b8e1f9691932 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_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/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/messageparcelmock003_fuzzer.cpp b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/messageparcelmock003_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3611c08373c01ba6e49817754e29a0b36ac87fc0 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/messageparcelmock003_fuzzer.cpp @@ -0,0 +1,184 @@ +/* + * 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 "messageparcelmock_fuzzer.h" +#include "ipc_object_stub.h" +#include "ipc_file_descriptor.h" +#include "iremote_object.h" +#include "ipc_process_skeleton.h" +#include "process_skeleton.h" +#include "message_parcel.h" +#include "sys_binder.h" +#include +#include +#include +#include + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +const static size_t MAX_STRING_PARAM_LEN = 100; + +class MessageParcelInstence { +public: + MessageParcelInstence() {}; + virtual ~MessageParcelInstence() {}; + + virtual size_t GetOffsetsSize() = 0; + virtual size_t GetDataSize() = 0; + virtual binder_size_t GetObjectOffsets() = 0; + virtual bool WriteBuffer(const void *data, size_t size) = 0; + virtual bool EnsureObjectsCapacity() = 0; +}; + +class MessageParcelInstenceMock : public MessageParcelInstence { +public: + MessageParcelInstenceMock(); + ~MessageParcelInstenceMock() override; + + MOCK_METHOD0(GetOffsetsSize, size_t()); + MOCK_METHOD0(GetDataSize, size_t()); + MOCK_METHOD0(GetObjectOffsets, binder_size_t()); + MOCK_METHOD2(WriteBuffer, bool(const void *data, size_t size)); + MOCK_METHOD0(EnsureObjectsCapacity, bool()); +}; + +static void *g_interface = nullptr; + +MessageParcelInstenceMock::MessageParcelInstenceMock() +{ + g_interface = reinterpret_cast(this); +} + +MessageParcelInstenceMock::~MessageParcelInstenceMock() +{ + g_interface = nullptr; +} + +static MessageParcelInstenceMock *GetMessageParcelInstenceMock() +{ + return reinterpret_cast(g_interface); +} + +extern "C" { + size_t Parcel::GetOffsetsSize() const + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->GetOffsetsSize(); + } + + size_t Parcel::GetDataSize() const + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->GetDataSize(); + } + + binder_size_t Parcel::GetObjectOffsets() const + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->GetObjectOffsets(); + } + + bool Parcel::WriteBuffer(const void *data, size_t size) + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->WriteBuffer(data, size); + } + + bool Parcel::EnsureObjectsCapacity() + { + MessageParcelInstenceMock* interface = GetMessageParcelInstenceMock(); + if (interface == nullptr) { + return false; + } + return interface->EnsureObjectsCapacity(); + } +} + +void AppendFuzzTest001(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + MessageParcel data; + std::string dataParcel = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + data.WriteBuffer(dataParcel.data(), dataParcel.size()); + NiceMock mock; + EXPECT_CALL(mock, GetDataSize).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(mock, WriteBuffer).WillOnce(Return(false)); + parcel.Append(data); + + EXPECT_CALL(mock, WriteBuffer).WillRepeatedly(testing::Return(true)); + EXPECT_CALL(mock, GetOffsetsSize).WillOnce(Return(0)); + parcel.Append(data); +} + +void AppendFuzzTest002(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + MessageParcel data; + std::string dataParcel = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + data.WriteBuffer(dataParcel.data(), dataParcel.size()); + NiceMock mock; + EXPECT_CALL(mock, GetDataSize).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(mock, WriteBuffer).WillRepeatedly(testing::Return(true)); + binder_size_t offsetArray[2] = {0x400, 0x800}; + EXPECT_CALL(mock, GetOffsetsSize).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(mock, GetObjectOffsets).WillRepeatedly(testing::Return(reinterpret_cast(offsetArray))); + EXPECT_CALL(mock, EnsureObjectsCapacity).WillOnce(Return(false)); + parcel.Append(data); + + EXPECT_CALL(mock, EnsureObjectsCapacity).WillRepeatedly(testing::Return(true)); + parcel.Append(data); +} + +void PrintBufferFuzzTest(FuzzedDataProvider &provider) +{ + MessageParcel parcel; + std::string dataParcel = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + parcel.WriteBuffer(dataParcel.data(), dataParcel.size()); + size_t lineNum = provider.ConsumeIntegral(); + parcel.PrintBuffer(nullptr, lineNum); + + std::string funcName = provider.ConsumeRandomLengthString(MAX_STRING_PARAM_LEN); + NiceMock mock; + binder_size_t offsetArray[2] = {0x400, 0x800}; + EXPECT_CALL(mock, GetOffsetsSize).WillOnce(Return(1)); + EXPECT_CALL(mock, GetObjectOffsets).WillOnce(Return(reinterpret_cast(offsetArray))); + parcel.PrintBuffer(funcName.c_str(), lineNum); +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + /* Run your code on data */ + FuzzedDataProvider provider(data, size); + OHOS::AppendFuzzTest001(provider); + OHOS::AppendFuzzTest002(provider); + OHOS::PrintBufferFuzzTest(provider); + return 0; +} diff --git a/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/project.xml b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..226522bd2ad3eaf2db4f710f1924d82d2912c235 --- /dev/null +++ b/test/fuzztest/interfaces/innerkits/ipc_core/messageparcelmock/messageparcelmock003_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 10000 + + 300 + + 4096 + + diff --git a/test/resource/ipc/ohos_test.xml b/test/resource/ipc/ohos_test.xml index 57242401f1638f2f61f163ed24b91520eb471526..c0d976dd23bc9a1e88f771d5bb60d55844a8ae14 100644 --- a/test/resource/ipc/ohos_test.xml +++ b/test/resource/ipc/ohos_test.xml @@ -473,4 +473,22 @@