From 32af30d826cd22ad48f70be9f4d9a9c5fd9189f8 Mon Sep 17 00:00:00 2001 From: wujianlin Date: Thu, 10 Oct 2024 17:05:08 +0800 Subject: [PATCH] ValidateReadData extend valida region Issue:https://gitee.com/openharmony/commonlibrary_c_utils/issues/IAW2DV?from=project-issue Signed-off-by: wujianlin --- base/src/parcel.cpp | 4 +- .../unittest/common/utils_parcel_test.cpp | 167 ++++++++++++++++++ 2 files changed, 170 insertions(+), 1 deletion(-) diff --git a/base/src/parcel.cpp b/base/src/parcel.cpp index b6edcfc..4696e5c 100644 --- a/base/src/parcel.cpp +++ b/base/src/parcel.cpp @@ -183,7 +183,9 @@ bool Parcel::ValidateReadData([[maybe_unused]]size_t upperBound) size_t nextObj = nextObjectIdx_; do { if (readPos < objects[nextObj] + sizeof(parcel_flat_binder_object)) { - return IsReadObjectData(nextObj, upperBound); + if (!IsReadObjectData(nextObj, upperBound)) { + return false; + } } nextObj++; } while (nextObj < objSize && upperBound > objects[nextObj]); diff --git a/base/test/unittest/common/utils_parcel_test.cpp b/base/test/unittest/common/utils_parcel_test.cpp index 0961b58..255d937 100644 --- a/base/test/unittest/common/utils_parcel_test.cpp +++ b/base/test/unittest/common/utils_parcel_test.cpp @@ -26,6 +26,8 @@ using namespace std; namespace OHOS { namespace { +static const int BINDER_TYPE_HANDLE = 0x73682a85; // binder header type handle +static const int BINDER_TYPE_FD = 0x66642a85; // binder header type fd const int MAX_PARCEL_SIZE = 1000; char g_data[MAX_PARCEL_SIZE]; class UtilsParcelTest : public testing::Test { @@ -74,6 +76,70 @@ sptr RemoteObject::Unmarshalling(Parcel &parcel) return obj; } +class RemoteFdObject : public virtual Parcelable { +public: + RemoteFdObject() { asRemote_ = true; }; + bool Marshalling(Parcel &parcel) const override; + static sptr Unmarshalling(Parcel &parcel); +}; + +bool RemoteFdObject::Marshalling(Parcel &parcel) const +{ + parcel_flat_binder_object flat; + flat.hdr.type = BINDER_TYPE_FD; + flat.flags = 0x7f; + flat.binder = 0; + flat.handle = (uint32_t)(-1); + flat.cookie = reinterpret_cast(this); + bool status = parcel.WriteBuffer(&flat, sizeof(parcel_flat_binder_object)); + if (!status) { + return false; + } + return true; +} + +sptr RemoteFdObject::Unmarshalling(Parcel &parcel) +{ + const uint8_t *buffer = parcel.ReadBuffer(sizeof(parcel_flat_binder_object), false); + if (buffer == nullptr) { + return nullptr; + } + sptr obj = new RemoteFdObject(); + return obj; +} + +class RemoteHandleObject : public virtual Parcelable { +public: + RemoteHandleObject() { asRemote_ = true; }; + bool Marshalling(Parcel &parcel) const override; + static sptr Unmarshalling(Parcel &parcel); +}; + +bool RemoteHandleObject::Marshalling(Parcel &parcel) const +{ + parcel_flat_binder_object flat; + flat.hdr.type = BINDER_TYPE_HANDLE; + flat.flags = 0x7f; + flat.binder = 0; + flat.handle = (uint32_t)(-1); + flat.cookie = reinterpret_cast(this); + bool status = parcel.WriteBuffer(&flat, sizeof(parcel_flat_binder_object)); + if (!status) { + return false; + } + return true; +} + +sptr RemoteHandleObject::Unmarshalling(Parcel &parcel) +{ + const uint8_t *buffer = parcel.ReadBuffer(sizeof(parcel_flat_binder_object), false); + if (buffer == nullptr) { + return nullptr; + } + sptr obj = new RemoteHandleObject(); + return obj; +} + /*-------------------------------base data------------------------------------*/ struct TestData { @@ -1970,6 +2036,107 @@ HWTEST_F(UtilsParcelTest, test_ValidateReadData_002, TestSize.Level0) EXPECT_EQ(true, readObj1.GetRefPtr() == nullptr); } +HWTEST_F(UtilsParcelTest, test_multiRemoteObjectReadBuffer_001, TestSize.Level0) +{ + Parcel parcel(nullptr); + + RemoteFdObject obj1; + bool result = parcel.WriteRemoteObject(&obj1); + EXPECT_EQ(result, true); + + RemoteHandleObject obj2; + result = parcel.WriteRemoteObject(&obj2); + EXPECT_EQ(result, true); + + RemoteObject obj3; + result = parcel.WriteRemoteObject(&obj3); + EXPECT_EQ(result, true); + + const uint8_t *buffer = parcel.ReadBuffer(sizeof(parcel_flat_binder_object) * 3); + EXPECT_EQ(true, buffer == nullptr); +} + +HWTEST_F(UtilsParcelTest, test_multiRemoteObjectReadBuffer_002, TestSize.Level0) +{ + Parcel parcel(nullptr); + + RemoteFdObject obj1; + bool result = parcel.WriteRemoteObject(&obj1); + EXPECT_EQ(result, true); + + RemoteObject obj2; + result = parcel.WriteRemoteObject(&obj2); + EXPECT_EQ(result, true); + + RemoteHandleObject obj3; + result = parcel.WriteRemoteObject(&obj3); + EXPECT_EQ(result, true); + + const uint8_t *buffer = parcel.ReadBuffer(sizeof(parcel_flat_binder_object) * 3); + EXPECT_EQ(true, buffer == nullptr); +} + +HWTEST_F(UtilsParcelTest, test_multiRemoteObjectReadBuffer_003, TestSize.Level0) +{ + Parcel parcel(nullptr); + + RemoteObject obj1; + bool result = parcel.WriteRemoteObject(&obj1); + EXPECT_EQ(result, true); + + RemoteHandleObject obj2; + result = parcel.WriteRemoteObject(&obj2); + EXPECT_EQ(result, true); + + RemoteFdObject obj3; + result = parcel.WriteRemoteObject(&obj3); + EXPECT_EQ(result, true); + + const uint8_t *buffer = parcel.ReadBuffer(sizeof(parcel_flat_binder_object) * 3); + EXPECT_EQ(true, buffer == nullptr); +} + +HWTEST_F(UtilsParcelTest, test_multiRemoteObjectReadBuffer_004, TestSize.Level0) +{ + Parcel parcel(nullptr); + + RemoteFdObject obj1; + bool result = parcel.WriteRemoteObject(&obj1); + EXPECT_EQ(result, true); + + RemoteHandleObject obj2; + result = parcel.WriteRemoteObject(&obj2); + EXPECT_EQ(result, true); + + RemoteFdObject obj3; + result = parcel.WriteRemoteObject(&obj3); + EXPECT_EQ(result, true); + + const uint8_t *buffer = parcel.ReadBuffer(sizeof(parcel_flat_binder_object) * 3); + EXPECT_EQ(true, buffer != nullptr); +} + +HWTEST_F(UtilsParcelTest, test_multiRemoteObjectReadBuffer_005, TestSize.Level0) +{ + Parcel parcel(nullptr); + + RemoteFdObject obj1; + bool result = parcel.WriteRemoteObject(&obj1); + EXPECT_EQ(result, true); + + RemoteObject obj2; + result = parcel.WriteRemoteObject(&obj2); + EXPECT_EQ(result, true); + + RemoteHandleObject obj3; + result = parcel.WriteRemoteObject(&obj3); + EXPECT_EQ(result, true); + + size_t readLength = 36; + const uint8_t *buffer = parcel.ReadBuffer(readLength); + EXPECT_EQ(true, buffer == nullptr); +} + HWTEST_F(UtilsParcelTest, test_RewindWrite_001, TestSize.Level0) { Parcel parcel(nullptr); -- Gitee