Loading libs/binder/Parcel.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -739,6 +739,17 @@ bool Parcel::enforceInterface(const char16_t* interface, } } binder::Status Parcel::enforceNoDataAvail() const { const auto n = dataAvail(); if (n == 0) { return binder::Status::ok(); } return binder::Status:: fromExceptionCode(binder::Status::Exception::EX_BAD_PARCELABLE, String8::format("Parcel data not fully consumed, unread size: %zu", n)); } size_t Parcel::objectsCount() const { return mObjectsSize; Loading libs/binder/include/binder/Parcel.h +7 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,9 @@ class ProcessState; class RpcSession; class String8; class TextOutput; namespace binder { class Status; } class Parcel { friend class IPCThreadState; Loading Loading @@ -131,6 +134,10 @@ public: IPCThreadState* threadState = nullptr) const; bool checkInterface(IBinder*) const; // Verify there are no bytes left to be read on the Parcel. // Returns Status(EX_BAD_PARCELABLE) when the Parcel is not consumed. binder::Status enforceNoDataAvail() const; void freeData(); size_t objectsCount() const; Loading libs/binder/tests/binderParcelUnitTest.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -16,15 +16,17 @@ #include <binder/IPCThreadState.h> #include <binder/Parcel.h> #include <binder/Status.h> #include <cutils/ashmem.h> #include <gtest/gtest.h> using android::IPCThreadState; using android::OK; using android::Parcel; using android::status_t; using android::String16; using android::String8; using android::status_t; using android::binder::Status; TEST(Parcel, NonNullTerminatedString8) { String8 kTestString = String8("test-is-good"); Loading Loading @@ -60,6 +62,19 @@ TEST(Parcel, NonNullTerminatedString16) { EXPECT_EQ(output.size(), 0); } TEST(Parcel, EnforceNoDataAvail) { const int32_t kTestInt = 42; const String8 kTestString = String8("test-is-good"); Parcel p; p.writeInt32(kTestInt); p.writeString8(kTestString); p.setDataPosition(0); EXPECT_EQ(kTestInt, p.readInt32()); EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_BAD_PARCELABLE); EXPECT_EQ(kTestString, p.readString8()); EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_NONE); } // Tests a second operation results in a parcel at the same location as it // started. void parcelOpSameLength(const std::function<void(Parcel*)>& a, const std::function<void(Parcel*)>& b) { Loading libs/binder/tests/parcel_fuzzer/binder.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <android/os/IServiceManager.h> #include <binder/ParcelableHolder.h> #include <binder/PersistableBundle.h> #include <binder/Status.h> using ::android::status_t; using ::android::base::HexString; Loading Loading @@ -100,6 +101,7 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS { PARCEL_READ_NO_STATUS(size_t, dataAvail), PARCEL_READ_NO_STATUS(size_t, dataPosition), PARCEL_READ_NO_STATUS(size_t, dataCapacity), PARCEL_READ_NO_STATUS(::android::binder::Status, enforceNoDataAvail), [] (const ::android::Parcel& p, uint8_t pos) { FUZZ_LOG() << "about to setDataPosition: " << pos; p.setDataPosition(pos); Loading Loading
libs/binder/Parcel.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -739,6 +739,17 @@ bool Parcel::enforceInterface(const char16_t* interface, } } binder::Status Parcel::enforceNoDataAvail() const { const auto n = dataAvail(); if (n == 0) { return binder::Status::ok(); } return binder::Status:: fromExceptionCode(binder::Status::Exception::EX_BAD_PARCELABLE, String8::format("Parcel data not fully consumed, unread size: %zu", n)); } size_t Parcel::objectsCount() const { return mObjectsSize; Loading
libs/binder/include/binder/Parcel.h +7 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,9 @@ class ProcessState; class RpcSession; class String8; class TextOutput; namespace binder { class Status; } class Parcel { friend class IPCThreadState; Loading Loading @@ -131,6 +134,10 @@ public: IPCThreadState* threadState = nullptr) const; bool checkInterface(IBinder*) const; // Verify there are no bytes left to be read on the Parcel. // Returns Status(EX_BAD_PARCELABLE) when the Parcel is not consumed. binder::Status enforceNoDataAvail() const; void freeData(); size_t objectsCount() const; Loading
libs/binder/tests/binderParcelUnitTest.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -16,15 +16,17 @@ #include <binder/IPCThreadState.h> #include <binder/Parcel.h> #include <binder/Status.h> #include <cutils/ashmem.h> #include <gtest/gtest.h> using android::IPCThreadState; using android::OK; using android::Parcel; using android::status_t; using android::String16; using android::String8; using android::status_t; using android::binder::Status; TEST(Parcel, NonNullTerminatedString8) { String8 kTestString = String8("test-is-good"); Loading Loading @@ -60,6 +62,19 @@ TEST(Parcel, NonNullTerminatedString16) { EXPECT_EQ(output.size(), 0); } TEST(Parcel, EnforceNoDataAvail) { const int32_t kTestInt = 42; const String8 kTestString = String8("test-is-good"); Parcel p; p.writeInt32(kTestInt); p.writeString8(kTestString); p.setDataPosition(0); EXPECT_EQ(kTestInt, p.readInt32()); EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_BAD_PARCELABLE); EXPECT_EQ(kTestString, p.readString8()); EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_NONE); } // Tests a second operation results in a parcel at the same location as it // started. void parcelOpSameLength(const std::function<void(Parcel*)>& a, const std::function<void(Parcel*)>& b) { Loading
libs/binder/tests/parcel_fuzzer/binder.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <android/os/IServiceManager.h> #include <binder/ParcelableHolder.h> #include <binder/PersistableBundle.h> #include <binder/Status.h> using ::android::status_t; using ::android::base::HexString; Loading Loading @@ -100,6 +101,7 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS { PARCEL_READ_NO_STATUS(size_t, dataAvail), PARCEL_READ_NO_STATUS(size_t, dataPosition), PARCEL_READ_NO_STATUS(size_t, dataCapacity), PARCEL_READ_NO_STATUS(::android::binder::Status, enforceNoDataAvail), [] (const ::android::Parcel& p, uint8_t pos) { FUZZ_LOG() << "about to setDataPosition: " << pos; p.setDataPosition(pos); Loading