diff options
author | Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> | 2024-03-05 18:55:58 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-03-05 18:55:58 +0000 |
commit | 1a0675170270fe07d5bd5f1e4a30887758046acc (patch) | |
tree | 23a2dc46b0d94625511fc8f4b9ee196dd2fda99d | |
parent | 3aa13d0d7dce6e69cc079ac85ae66cbf4491e421 (diff) | |
parent | aa9d3a357019817d26812f39fda18f89238a4f4f (diff) | |
download | native-1a0675170270fe07d5bd5f1e4a30887758046acc.tar.gz |
Merge "libbinder: add hasBinders" into main
-rw-r--r-- | libs/binder/Parcel.cpp | 50 | ||||
-rw-r--r-- | libs/binder/include/binder/Parcel.h | 4 | ||||
-rw-r--r-- | libs/binder/tests/binderParcelUnitTest.cpp | 40 | ||||
-rw-r--r-- | libs/binder/tests/parcel_fuzzer/binder.cpp | 14 |
4 files changed, 106 insertions, 2 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 7a54a03389..604e5355cb 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -216,7 +216,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) { if (const auto* rpcFields = maybeRpcFields()) { if (binder) { - status_t status = writeInt32(1); // non-null + status_t status = writeInt32(RpcFields::TYPE_BINDER); // non-null if (status != OK) return status; uint64_t address; // TODO(b/167966510): need to undo this if the Parcel is not sent @@ -226,7 +226,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) { status = writeUint64(address); if (status != OK) return status; } else { - status_t status = writeInt32(0); // null + status_t status = writeInt32(RpcFields::TYPE_BINDER_NULL); // null if (status != OK) return status; } return finishFlattenBinder(binder); @@ -699,6 +699,12 @@ bool Parcel::hasFileDescriptors() const return kernelFields->mHasFds; } +status_t Parcel::hasBinders(bool* result) const { + status_t status = hasBindersInRange(0, dataSize(), result); + ALOGE_IF(status != NO_ERROR, "Error %d calling hasBindersInRange()", status); + return status; +} + std::vector<sp<IBinder>> Parcel::debugReadAllStrongBinders() const { std::vector<sp<IBinder>> ret; @@ -758,6 +764,46 @@ std::vector<int> Parcel::debugReadAllFileDescriptors() const { return ret; } +status_t Parcel::hasBindersInRange(size_t offset, size_t len, bool* result) const { + if (len > INT32_MAX || offset > INT32_MAX) { + // Don't accept size_t values which may have come from an inadvertent conversion from a + // negative int. + return BAD_VALUE; + } + size_t limit; + if (__builtin_add_overflow(offset, len, &limit) || limit > mDataSize) { + return BAD_VALUE; + } + *result = false; + if (const auto* kernelFields = maybeKernelFields()) { +#ifdef BINDER_WITH_KERNEL_IPC + for (size_t i = 0; i < kernelFields->mObjectsSize; i++) { + size_t pos = kernelFields->mObjects[i]; + if (pos < offset) continue; + if (pos + sizeof(flat_binder_object) > offset + len) { + if (kernelFields->mObjectsSorted) { + break; + } else { + continue; + } + } + const flat_binder_object* flat = + reinterpret_cast<const flat_binder_object*>(mData + pos); + if (flat->hdr.type == BINDER_TYPE_BINDER || flat->hdr.type == BINDER_TYPE_HANDLE) { + *result = true; + break; + } + } +#else + LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + return INVALID_OPERATION; +#endif // BINDER_WITH_KERNEL_IPC + } else if (const auto* rpcFields = maybeRpcFields()) { + return INVALID_OPERATION; + } + return NO_ERROR; +} + status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* result) const { if (len > INT32_MAX || offset > INT32_MAX) { // Don't accept size_t values which may have come from an inadvertent conversion from a diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index d7096d8a75..5e18b9197d 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -101,7 +101,9 @@ public: void restoreAllowFds(bool lastValue); bool hasFileDescriptors() const; + status_t hasBinders(bool* result) const; status_t hasFileDescriptorsInRange(size_t offset, size_t length, bool* result) const; + status_t hasBindersInRange(size_t offset, size_t length, bool* result) const; // returns all binder objects in the Parcel std::vector<sp<IBinder>> debugReadAllStrongBinders() const; @@ -647,6 +649,8 @@ private: void freeDataNoInit(); void initState(); void scanForFds() const; + status_t scanForBinders(bool* result) const; + status_t validateReadData(size_t len) const; void updateWorkSourceRequestHeaderPosition() const; diff --git a/libs/binder/tests/binderParcelUnitTest.cpp b/libs/binder/tests/binderParcelUnitTest.cpp index 34fc43f926..32a70e5b11 100644 --- a/libs/binder/tests/binderParcelUnitTest.cpp +++ b/libs/binder/tests/binderParcelUnitTest.cpp @@ -23,6 +23,7 @@ using android::BBinder; using android::IBinder; using android::IPCThreadState; +using android::NO_ERROR; using android::OK; using android::Parcel; using android::sp; @@ -164,6 +165,45 @@ TEST(Parcel, AppendPlainDataPartial) { ASSERT_EQ(2, p2.readInt32()); } +TEST(Parcel, HasBinders) { + sp<IBinder> b1 = sp<BBinder>::make(); + + Parcel p1; + p1.writeInt32(1); + p1.writeStrongBinder(b1); + + bool result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); + + p1.setDataSize(0); // clear data + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(false, result); + p1.writeStrongBinder(b1); // reset with binder data + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); + + Parcel p3; + p3.appendFrom(&p1, 0, p1.dataSize()); + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); +} + +TEST(Parcel, HasBindersInRange) { + sp<IBinder> b1 = sp<BBinder>::make(); + Parcel p1; + p1.writeStrongBinder(b1); + bool result = false; + ASSERT_EQ(NO_ERROR, p1.hasBindersInRange(0, p1.dataSize(), &result)); + ASSERT_EQ(true, result); + result = false; + ASSERT_EQ(NO_ERROR, p1.hasBinders(&result)); + ASSERT_EQ(true, result); +} + TEST(Parcel, AppendWithBinder) { sp<IBinder> b1 = sp<BBinder>::make(); sp<IBinder> b2 = sp<BBinder>::make(); diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp index 08fe071bfb..5c280f4b2c 100644 --- a/libs/binder/tests/parcel_fuzzer/binder.cpp +++ b/libs/binder/tests/parcel_fuzzer/binder.cpp @@ -353,6 +353,20 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS { FUZZ_LOG() << " status: " << status << " result: " << result; }, [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { + FUZZ_LOG() << "about to call hasBinders() with status"; + bool result; + status_t status = p.hasBinders(&result); + FUZZ_LOG() << " status: " << status << " result: " << result; + }, + [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { + FUZZ_LOG() << "about to call hasBindersInRange() with status"; + size_t offset = p.readUint32(); + size_t length = p.readUint32(); + bool result; + status_t status = p.hasBindersInRange(offset, length, &result); + FUZZ_LOG() << " status: " << status << " result: " << result; + }, + [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { FUZZ_LOG() << "about to call compareDataInRange() with status"; size_t thisOffset = p.readUint32(); size_t otherOffset = p.readUint32(); |