diff options
| author | 2021-12-24 05:18:25 +0000 | |
|---|---|---|
| committer | 2021-12-24 05:18:25 +0000 | |
| commit | c5da00e08e24c03e5d2a5953db28af6552cec22c (patch) | |
| tree | 0d5d097f2ed5ca549ca8b2dcdfb889dca60dff06 | |
| parent | 4d95851db86d5c51eb3b03382f516f21485fb8f7 (diff) | |
| parent | d23f9500efa59d46c57db423a630b111e889a680 (diff) | |
Merge "libbinder: added enforceNoDataAvail()"
| -rw-r--r-- | libs/binder/Parcel.cpp | 11 | ||||
| -rw-r--r-- | libs/binder/include/binder/Parcel.h | 7 | ||||
| -rw-r--r-- | libs/binder/tests/binderParcelUnitTest.cpp | 17 | ||||
| -rw-r--r-- | libs/binder/tests/parcel_fuzzer/binder.cpp | 2 | 
4 files changed, 36 insertions, 1 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 7027a4b0a3..6fb189cd70 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -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; diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 8dbdc1d115..450e3888f1 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -54,6 +54,9 @@ class ProcessState;  class RpcSession;  class String8;  class TextOutput; +namespace binder { +class Status; +}  class Parcel {      friend class IPCThreadState; @@ -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; diff --git a/libs/binder/tests/binderParcelUnitTest.cpp b/libs/binder/tests/binderParcelUnitTest.cpp index 4950b23858..aee15d8bd9 100644 --- a/libs/binder/tests/binderParcelUnitTest.cpp +++ b/libs/binder/tests/binderParcelUnitTest.cpp @@ -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"); @@ -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) { diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp index 077d915ca1..13f7195eb7 100644 --- a/libs/binder/tests/parcel_fuzzer/binder.cpp +++ b/libs/binder/tests/parcel_fuzzer/binder.cpp @@ -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; @@ -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);  |