Merge "Testing AIDL delegator class with RPC"
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index bb1b513..2ecb895 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -153,10 +153,6 @@
export_aidl_headers: true,
},
- // TODO(b/142684679): for com.android.media which is compiled
- // as vendor and used as system code.
- use_apex_name_macro: true,
-
cflags: [
"-Wall",
"-Wextra",
diff --git a/libs/binder/OWNERS b/libs/binder/OWNERS
index 350994a..1c8bdea 100644
--- a/libs/binder/OWNERS
+++ b/libs/binder/OWNERS
@@ -1,5 +1,7 @@
+# Bug component: 32456
arve@google.com
ctate@google.com
hackbod@google.com
maco@google.com
smoreland@google.com
+tkjos@google.com
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 07555f6..805e576 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -98,9 +98,8 @@
BLOB_ASHMEM_MUTABLE = 2,
};
-static void acquire_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
-{
+static void acquire_object(const sp<ProcessState>& proc, const flat_binder_object& obj,
+ const void* who) {
switch (obj.hdr.type) {
case BINDER_TYPE_BINDER:
if (obj.binder) {
@@ -117,13 +116,6 @@
return;
}
case BINDER_TYPE_FD: {
- if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
- // If we own an ashmem fd, keep track of how much memory it refers to.
- int size = ashmem_get_size_region(obj.handle);
- if (size > 0) {
- *outAshmemSize += size;
- }
- }
return;
}
}
@@ -131,9 +123,8 @@
ALOGD("Invalid object type 0x%08x", obj.hdr.type);
}
-static void release_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
-{
+static void release_object(const sp<ProcessState>& proc, const flat_binder_object& obj,
+ const void* who) {
switch (obj.hdr.type) {
case BINDER_TYPE_BINDER:
if (obj.binder) {
@@ -151,16 +142,6 @@
}
case BINDER_TYPE_FD: {
if (obj.cookie != 0) { // owned
- if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
- int size = ashmem_get_size_region(obj.handle);
- if (size > 0) {
- // ashmem size might have changed since last time it was accounted for, e.g.
- // in acquire_object(). Value of *outAshmemSize is not critical since we are
- // releasing the object anyway. Check for integer overflow condition.
- *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
- }
- }
-
close(obj.handle);
}
return;
@@ -430,8 +411,9 @@
status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
{
- if (parcel->isForRpc() != isForRpc()) {
- ALOGE("Cannot append Parcel of one format to another.");
+ if (mSession != parcel->mSession) {
+ ALOGE("Cannot append Parcel from one context to another. They may be different formats, "
+ "and objects are specific to a context.");
return BAD_TYPE;
}
@@ -512,7 +494,7 @@
flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(mData + off);
- acquire_object(proc, *flat, this, &mOpenAshmemSize);
+ acquire_object(proc, *flat, this);
if (flat->hdr.type == BINDER_TYPE_FD) {
// If this is a file descriptor, we need to dup it so the
@@ -566,6 +548,36 @@
return mHasFds;
}
+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
+ // negative int.
+ return BAD_VALUE;
+ }
+ size_t limit = offset + len;
+ if (offset > mDataSize || len > mDataSize || limit > mDataSize || offset > limit) {
+ return BAD_VALUE;
+ }
+ result = hasFileDescriptorsInRangeUnchecked(offset, len);
+ return NO_ERROR;
+}
+
+bool Parcel::hasFileDescriptorsInRangeUnchecked(size_t offset, size_t len) const {
+ for (size_t i = 0; i < mObjectsSize; i++) {
+ size_t pos = mObjects[i];
+ if (pos < offset) continue;
+ if (pos + sizeof(flat_binder_object) > offset + len) {
+ if (mObjectsSorted) break;
+ else continue;
+ }
+ const flat_binder_object* flat = reinterpret_cast<const flat_binder_object*>(mData + pos);
+ if (flat->hdr.type == BINDER_TYPE_FD) {
+ return true;
+ }
+ }
+ return false;
+}
+
void Parcel::markSensitive() const
{
mDeallocZero = true;
@@ -1335,7 +1347,7 @@
// Need to write meta-data?
if (nullMetaData || val.binder != 0) {
mObjects[mObjectsSize] = mDataPos;
- acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
+ acquire_object(ProcessState::self(), val, this);
mObjectsSize++;
}
@@ -2225,7 +2237,7 @@
i--;
const flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(data+objects[i]);
- release_object(proc, *flat, this, &mOpenAshmemSize);
+ release_object(proc, *flat, this);
}
}
@@ -2242,7 +2254,7 @@
i--;
const flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(data+objects[i]);
- acquire_object(proc, *flat, this, &mOpenAshmemSize);
+ acquire_object(proc, *flat, this);
}
}
@@ -2447,7 +2459,7 @@
// will need to rescan because we may have lopped off the only FDs
mFdsKnown = false;
}
- release_object(proc, *flat, this, &mOpenAshmemSize);
+ release_object(proc, *flat, this);
}
if (objectsSize == 0) {
@@ -2540,7 +2552,6 @@
mAllowFds = true;
mDeallocZero = false;
mOwner = nullptr;
- mOpenAshmemSize = 0;
mWorkSourceRequestHeaderPosition = 0;
mRequestHeaderPresent = false;
@@ -2559,16 +2570,7 @@
void Parcel::scanForFds() const
{
- bool hasFds = false;
- for (size_t i=0; i<mObjectsSize; i++) {
- const flat_binder_object* flat
- = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
- if (flat->hdr.type == BINDER_TYPE_FD) {
- hasFds = true;
- break;
- }
- }
- mHasFds = hasFds;
+ mHasFds = hasFileDescriptorsInRangeUnchecked(0, dataSize());
mFdsKnown = true;
}
@@ -2576,13 +2578,28 @@
{
// This used to return the size of all blobs that were written to ashmem, now we're returning
// the ashmem currently referenced by this Parcel, which should be equivalent.
- // TODO: Remove method once ABI can be changed.
- return mOpenAshmemSize;
+ // TODO(b/202029388): Remove method once ABI can be changed.
+ return getOpenAshmemSize();
}
size_t Parcel::getOpenAshmemSize() const
{
- return mOpenAshmemSize;
+ size_t openAshmemSize = 0;
+ for (size_t i = 0; i < mObjectsSize; i++) {
+ const flat_binder_object* flat =
+ reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
+
+ // cookie is compared against zero for historical reasons
+ // > obj.cookie = takeOwnership ? 1 : 0;
+ if (flat->hdr.type == BINDER_TYPE_FD && flat->cookie != 0 && ashmem_valid(flat->handle)) {
+ int size = ashmem_get_size_region(flat->handle);
+ if (__builtin_add_overflow(openAshmemSize, size, &openAshmemSize)) {
+ ALOGE("Overflow when computing ashmem size.");
+ return SIZE_MAX;
+ }
+ }
+ }
+ return openAshmemSize;
}
// --- Parcel::Blob ---
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index fd8ac62..cf30f17 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -87,6 +87,7 @@
void restoreAllowFds(bool lastValue);
bool hasFileDescriptors() const;
+ status_t hasFileDescriptorsInRange(size_t offset, size_t length, bool& result) const;
// Zeros data when reallocating. Other mitigations may be added
// in the future.
@@ -575,6 +576,7 @@
status_t writeRawNullableParcelable(const Parcelable*
parcelable);
+ bool hasFileDescriptorsInRangeUnchecked(size_t offset, size_t length) const;
//-----------------------------------------------------------------------------
// Generic type read and write methods for Parcel:
@@ -1141,6 +1143,7 @@
release_func mOwner;
sp<RpcSession> mSession;
+ size_t mReserved;
class Blob {
public:
@@ -1225,13 +1228,17 @@
inline void* data() { return mData; }
};
-private:
- size_t mOpenAshmemSize;
-
-public:
- // TODO: Remove once ABI can be changed.
- size_t getBlobAshmemSize() const;
+ /**
+ * Returns the total amount of ashmem memory owned by this object.
+ *
+ * Note: for historical reasons, this does not include ashmem memory which
+ * is referenced by this Parcel, but which this parcel doesn't own (e.g.
+ * writeFileDescriptor is called without 'takeOwnership' true).
+ */
size_t getOpenAshmemSize() const;
+
+ // TODO(b/202029388): Remove 'getBlobAshmemSize' once ABI can be changed.
+ size_t getBlobAshmemSize() const;
};
// ---------------------------------------------------------------------------
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
index 563d011..4a7b664 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
@@ -543,6 +543,28 @@
}
/**
+ * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_writeNullableStdVectorParcelableElement(AParcel* parcel,
+ const void* vectorData,
+ size_t index) {
+ const std::optional<std::vector<P>>* vector =
+ static_cast<const std::optional<std::vector<P>*>>(vectorData);
+ return AParcel_writeNullableParcelable(parcel, vector->at(index));
+}
+
+/**
+ * Reads a parcelable object of type P inside a std::vector<P> at index 'index' from 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_readNullableStdVectorParcelableElement(const AParcel* parcel,
+ void* vectorData, size_t index) {
+ std::optional<std::vector<P>>* vector = static_cast<std::optional<std::vector<P>>*>(vectorData);
+ return AParcel_readNullableParcelable(parcel, &vector->at(index));
+}
+
+/**
* Writes a ScopedFileDescriptor object inside a std::vector<ScopedFileDescriptor> at index 'index'
* to 'parcel'.
*/
@@ -579,6 +601,54 @@
}
/**
+ * Writes an SpAIBinder object inside a std::vector<SpAIBinder> at index 'index'
+ * to 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_writeStdVectorParcelableElement<SpAIBinder>(AParcel* parcel,
+ const void* vectorData,
+ size_t index) {
+ const std::vector<SpAIBinder>* vector = static_cast<const std::vector<SpAIBinder>*>(vectorData);
+ return AParcel_writeRequiredStrongBinder(parcel, vector->at(index));
+}
+
+/**
+ * Reads an SpAIBinder object inside a std::vector<SpAIBinder> at index 'index'
+ * from 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_readStdVectorParcelableElement<SpAIBinder>(const AParcel* parcel,
+ void* vectorData,
+ size_t index) {
+ std::vector<SpAIBinder>* vector = static_cast<std::vector<SpAIBinder>*>(vectorData);
+ return AParcel_readRequiredStrongBinder(parcel, &vector->at(index));
+}
+
+/**
+ * Writes an SpAIBinder object inside a std::optional<std::vector<SpAIBinder>> at index 'index'
+ * to 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_writeNullableStdVectorParcelableElement<SpAIBinder>(
+ AParcel* parcel, const void* vectorData, size_t index) {
+ const std::optional<std::vector<SpAIBinder>>* vector =
+ static_cast<const std::optional<std::vector<SpAIBinder>>*>(vectorData);
+ return AParcel_writeNullableStrongBinder(parcel, (*vector)->at(index));
+}
+
+/**
+ * Reads an SpAIBinder object inside a std::optional<std::vector<SpAIBinder>> at index 'index'
+ * from 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_readNullableStdVectorParcelableElement<SpAIBinder>(
+ const AParcel* parcel, void* vectorData, size_t index) {
+ std::optional<std::vector<SpAIBinder>>* vector =
+ static_cast<std::optional<std::vector<SpAIBinder>>*>(vectorData);
+ return AParcel_readNullableStrongBinder(parcel, &(*vector)->at(index));
+}
+
+/**
* Convenience API for writing a std::vector<P>
*/
template <typename P>
@@ -598,6 +668,30 @@
AParcel_readStdVectorParcelableElement<P>);
}
+/**
+ * Convenience API for writing a std::optional<std::vector<P>>
+ */
+template <typename P>
+static inline binder_status_t AParcel_writeVector(AParcel* parcel,
+ const std::optional<std::vector<P>>& vec) {
+ if (!vec) return AParcel_writeInt32(parcel, -1);
+ const void* vectorData = static_cast<const void*>(&vec);
+ return AParcel_writeParcelableArray(parcel, vectorData, static_cast<int32_t>(vec->size()),
+ AParcel_writeNullableStdVectorParcelableElement<P>);
+}
+
+/**
+ * Convenience API for reading a std::optional<std::vector<P>>
+ */
+template <typename P>
+static inline binder_status_t AParcel_readVector(const AParcel* parcel,
+ std::optional<std::vector<P>>* vec) {
+ void* vectorData = static_cast<void*>(vec);
+ return AParcel_readParcelableArray(parcel, vectorData,
+ AParcel_nullableStdVectorExternalAllocator<P>,
+ AParcel_readNullableStdVectorParcelableElement<P>);
+}
+
// @START
/**
* Writes a vector of int32_t to the next location in a non-null parcel.
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 68fa34b..6a4af07 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -430,6 +430,7 @@
impl SerializeArray for SpIBinder {}
impl SerializeArray for Option<&SpIBinder> {}
+impl SerializeArray for Option<SpIBinder> {}
impl Deserialize for SpIBinder {
fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index f989525..f132ff7 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -690,13 +690,21 @@
}
TEST_P(BinderRpc, AppendSeparateFormats) {
- auto proc = createRpcTestSocketServerProcess({});
+ auto proc1 = createRpcTestSocketServerProcess({});
+ auto proc2 = createRpcTestSocketServerProcess({});
+
+ Parcel pRaw;
Parcel p1;
- p1.markForBinder(proc.rootBinder);
+ p1.markForBinder(proc1.rootBinder);
p1.writeInt32(3);
+ EXPECT_EQ(BAD_TYPE, p1.appendFrom(&pRaw, 0, p1.dataSize()));
+ EXPECT_EQ(BAD_TYPE, pRaw.appendFrom(&p1, 0, p1.dataSize()));
+
Parcel p2;
+ p2.markForBinder(proc2.rootBinder);
+ p2.writeInt32(7);
EXPECT_EQ(BAD_TYPE, p1.appendFrom(&p2, 0, p2.dataSize()));
EXPECT_EQ(BAD_TYPE, p2.appendFrom(&p1, 0, p1.dataSize()));
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index f1fe164..55eb847 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -301,6 +301,14 @@
FUZZ_LOG() << "ParcelableHolder status: " << status;
},
PARCEL_READ_WITH_STATUS(android::os::PersistableBundle, readParcelable),
+ [] (const ::android::Parcel& p, uint8_t /* data */) {
+ FUZZ_LOG() << "about to call hasFileDescriptorsInRange() with status";
+ size_t offset = p.readUint32();
+ size_t length = p.readUint32();
+ bool result;
+ status_t status = p.hasFileDescriptorsInRange(offset, length, result);
+ FUZZ_LOG() << " status: " << status << " result: " << result;
+ },
};
// clang-format on
#pragma clang diagnostic pop
diff --git a/libs/vibrator/OWNERS b/libs/vibrator/OWNERS
index 0997e9f..d073e2b 100644
--- a/libs/vibrator/OWNERS
+++ b/libs/vibrator/OWNERS
@@ -1,2 +1 @@
-lsandrade@google.com
-michaelwr@google.com
+include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index bba6e22..1be5a96 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -77,7 +77,6 @@
"libsensor",
"libsensorprivacy",
"libpermission",
- "packagemanager_aidl-cpp",
],
}
diff --git a/services/vibratorservice/OWNERS b/services/vibratorservice/OWNERS
new file mode 100644
index 0000000..d073e2b
--- /dev/null
+++ b/services/vibratorservice/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS