diff options
-rw-r--r-- | cmds/installd/OWNERS | 1 | ||||
-rw-r--r-- | libs/binder/Binder.cpp | 36 | ||||
-rw-r--r-- | libs/binder/BpBinder.cpp | 44 | ||||
-rw-r--r-- | libs/binder/ServiceManagerHost.cpp | 9 | ||||
-rw-r--r-- | libs/binder/TEST_MAPPING | 2 | ||||
-rw-r--r-- | libs/binder/include/binder/Binder.h | 9 | ||||
-rw-r--r-- | libs/binder/include/binder/BpBinder.h | 33 | ||||
-rw-r--r-- | libs/binder/include/binder/IBinder.h | 34 | ||||
-rw-r--r-- | libs/binder/ndk/ibinder.cpp | 56 | ||||
-rw-r--r-- | libs/binder/ndk/ibinder_internal.h | 1 | ||||
-rw-r--r-- | libs/binder/rust/src/binder.rs | 2 | ||||
-rw-r--r-- | libs/binder/rust/src/native.rs | 19 | ||||
-rw-r--r-- | libs/binder/rust/src/proxy.rs | 14 | ||||
-rw-r--r-- | libs/binder/tests/Android.bp | 4 | ||||
-rw-r--r-- | libs/binder/tests/binderBinderUnitTest.cpp | 43 | ||||
-rw-r--r-- | libs/binder/tests/binderParcelUnitTest.cpp (renamed from libs/binder/tests/binderParcelTest.cpp) | 59 | ||||
-rw-r--r-- | libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h | 18 |
17 files changed, 239 insertions, 145 deletions
diff --git a/cmds/installd/OWNERS b/cmds/installd/OWNERS index d6807ffe26..643b2c2d11 100644 --- a/cmds/installd/OWNERS +++ b/cmds/installd/OWNERS @@ -4,7 +4,6 @@ calin@google.com jsharkey@android.com maco@google.com mast@google.com -mathieuc@google.com narayan@google.com ngeoffray@google.com rpl@google.com diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index 02321cdf97..628381cc19 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -179,6 +179,17 @@ status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd, return transact(SET_RPC_CLIENT_TRANSACTION, data, &reply); } +void IBinder::withLock(const std::function<void()>& doWithLock) { + BBinder* local = localBinder(); + if (local) { + local->withLock(doWithLock); + return; + } + BpBinder* proxy = this->remoteBinder(); + LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote"); + proxy->withLock(doWithLock); +} + // --------------------------------------------------------------------------- class BBinder::RpcServerLink : public IBinder::DeathRecipient { @@ -311,15 +322,13 @@ status_t BBinder::dump(int /*fd*/, const Vector<String16>& /*args*/) return NO_ERROR; } -void BBinder::attachObject( - const void* objectID, void* object, void* cleanupCookie, - object_cleanup_func func) -{ +void* BBinder::attachObject(const void* objectID, void* object, void* cleanupCookie, + object_cleanup_func func) { Extras* e = getOrCreateExtras(); - if (!e) return; // out of memory + LOG_ALWAYS_FATAL_IF(!e, "no memory"); AutoMutex _l(e->mLock); - e->mObjects.attach(objectID, object, cleanupCookie, func); + return e->mObjects.attach(objectID, object, cleanupCookie, func); } void* BBinder::findObject(const void* objectID) const @@ -331,13 +340,20 @@ void* BBinder::findObject(const void* objectID) const return e->mObjects.find(objectID); } -void BBinder::detachObject(const void* objectID) -{ +void* BBinder::detachObject(const void* objectID) { Extras* e = mExtras.load(std::memory_order_acquire); - if (!e) return; + if (!e) return nullptr; + + AutoMutex _l(e->mLock); + return e->mObjects.detach(objectID); +} + +void BBinder::withLock(const std::function<void()>& doWithLock) { + Extras* e = getOrCreateExtras(); + LOG_ALWAYS_FATAL_IF(!e, "no memory"); AutoMutex _l(e->mLock); - e->mObjects.detach(objectID); + doWithLock(); } BBinder* BBinder::localBinder() diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp index 5e44a0f7c1..3099296219 100644 --- a/libs/binder/BpBinder.cpp +++ b/libs/binder/BpBinder.cpp @@ -61,22 +61,22 @@ BpBinder::ObjectManager::~ObjectManager() kill(); } -void BpBinder::ObjectManager::attach( - const void* objectID, void* object, void* cleanupCookie, - IBinder::object_cleanup_func func) -{ +void* BpBinder::ObjectManager::attach(const void* objectID, void* object, void* cleanupCookie, + IBinder::object_cleanup_func func) { entry_t e; e.object = object; e.cleanupCookie = cleanupCookie; e.func = func; - if (mObjects.indexOfKey(objectID) >= 0) { - ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use", - objectID, this, object); - return; + if (ssize_t idx = mObjects.indexOfKey(objectID); idx >= 0) { + ALOGI("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object " + "ID already in use", + objectID, this, object); + return mObjects[idx].object; } mObjects.add(objectID, e); + return nullptr; } void* BpBinder::ObjectManager::find(const void* objectID) const @@ -86,9 +86,12 @@ void* BpBinder::ObjectManager::find(const void* objectID) const return mObjects.valueAt(i).object; } -void BpBinder::ObjectManager::detach(const void* objectID) -{ - mObjects.removeItem(objectID); +void* BpBinder::ObjectManager::detach(const void* objectID) { + ssize_t idx = mObjects.indexOfKey(objectID); + if (idx < 0) return nullptr; + void* value = mObjects[idx].object; + mObjects.removeItemsAt(idx, 1); + return value; } void BpBinder::ObjectManager::kill() @@ -406,14 +409,11 @@ void BpBinder::reportOneDeath(const Obituary& obit) recipient->binderDied(wp<BpBinder>::fromExisting(this)); } - -void BpBinder::attachObject( - const void* objectID, void* object, void* cleanupCookie, - object_cleanup_func func) -{ +void* BpBinder::attachObject(const void* objectID, void* object, void* cleanupCookie, + object_cleanup_func func) { AutoMutex _l(mLock); ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects); - mObjects.attach(objectID, object, cleanupCookie, func); + return mObjects.attach(objectID, object, cleanupCookie, func); } void* BpBinder::findObject(const void* objectID) const @@ -422,10 +422,14 @@ void* BpBinder::findObject(const void* objectID) const return mObjects.find(objectID); } -void BpBinder::detachObject(const void* objectID) -{ +void* BpBinder::detachObject(const void* objectID) { + AutoMutex _l(mLock); + return mObjects.detach(objectID); +} + +void BpBinder::withLock(const std::function<void()>& doWithLock) { AutoMutex _l(mLock); - mObjects.detach(objectID); + doWithLock(); } BpBinder* BpBinder::remoteBinder() diff --git a/libs/binder/ServiceManagerHost.cpp b/libs/binder/ServiceManagerHost.cpp index 07f5778deb..1c2f9b4314 100644 --- a/libs/binder/ServiceManagerHost.cpp +++ b/libs/binder/ServiceManagerHost.cpp @@ -167,9 +167,12 @@ sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs) { ALOGE("RpcSession::getRootObject returns nullptr"); return nullptr; } - binder->attachObject(kDeviceServiceExtraId, - static_cast<void*>(new CommandResult(std::move(*result))), nullptr, - &cleanupCommandResult); + + LOG_ALWAYS_FATAL_IF( + nullptr != + binder->attachObject(kDeviceServiceExtraId, + static_cast<void*>(new CommandResult(std::move(*result))), nullptr, + &cleanupCommandResult)); return binder; } diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING index 012a9befdc..269b867c83 100644 --- a/libs/binder/TEST_MAPPING +++ b/libs/binder/TEST_MAPPING @@ -22,7 +22,7 @@ "name": "binderTextOutputTest" }, { - "name": "binderParcelTest" + "name": "binderUnitTest" }, { "name": "binderLibTest" diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h index 472e546944..46223bb00e 100644 --- a/libs/binder/include/binder/Binder.h +++ b/libs/binder/include/binder/Binder.h @@ -54,12 +54,11 @@ public: uint32_t flags = 0, wp<DeathRecipient>* outRecipient = nullptr); - virtual void attachObject( const void* objectID, - void* object, - void* cleanupCookie, - object_cleanup_func func) final; + virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie, + object_cleanup_func func) final; virtual void* findObject(const void* objectID) const final; - virtual void detachObject(const void* objectID) final; + virtual void* detachObject(const void* objectID) final; + void withLock(const std::function<void()>& doWithLock); virtual BBinder* localBinder(); diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h index 61bf018e43..c69bb9e744 100644 --- a/libs/binder/include/binder/BpBinder.h +++ b/libs/binder/include/binder/BpBinder.h @@ -72,12 +72,11 @@ public: uint32_t flags = 0, wp<DeathRecipient>* outRecipient = nullptr); - virtual void attachObject( const void* objectID, - void* object, - void* cleanupCookie, - object_cleanup_func func) final; + virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie, + object_cleanup_func func) final; virtual void* findObject(const void* objectID) const final; - virtual void detachObject(const void* objectID) final; + virtual void* detachObject(const void* objectID) final; + void withLock(const std::function<void()>& doWithLock); virtual BpBinder* remoteBinder(); @@ -91,27 +90,23 @@ public: static void setLimitCallback(binder_proxy_limit_callback cb); static void setBinderProxyCountWatermarks(int high, int low); - class ObjectManager - { + class ObjectManager { public: - ObjectManager(); - ~ObjectManager(); + ObjectManager(); + ~ObjectManager(); - void attach( const void* objectID, - void* object, - void* cleanupCookie, - IBinder::object_cleanup_func func); - void* find(const void* objectID) const; - void detach(const void* objectID); + void* attach(const void* objectID, void* object, void* cleanupCookie, + IBinder::object_cleanup_func func); + void* find(const void* objectID) const; + void* detach(const void* objectID); - void kill(); + void kill(); private: - ObjectManager(const ObjectManager&); + ObjectManager(const ObjectManager&); ObjectManager& operator=(const ObjectManager&); - struct entry_t - { + struct entry_t { void* object; void* cleanupCookie; IBinder::object_cleanup_func func; diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h index f9cdac7de9..43fc5ff1a9 100644 --- a/libs/binder/include/binder/IBinder.h +++ b/libs/binder/include/binder/IBinder.h @@ -22,6 +22,8 @@ #include <utils/String16.h> #include <utils/Vector.h> +#include <functional> + // linux/binder.h defines this, but we don't want to include it here in order to // avoid exporting the kernel headers #ifndef B_PACK_CHARS @@ -255,26 +257,30 @@ public: * objects are invoked with their respective objectID, object, and * cleanupCookie. Access to these APIs can be made from multiple threads, * but calls from different threads are allowed to be interleaved. + * + * This returns the object which is already attached. If this returns a + * non-null value, it means that attachObject failed (a given objectID can + * only be used once). */ - virtual void attachObject( const void* objectID, - void* object, - void* cleanupCookie, - object_cleanup_func func) = 0; + [[nodiscard]] virtual void* attachObject(const void* objectID, void* object, + void* cleanupCookie, object_cleanup_func func) = 0; /** * Returns object attached with attachObject. */ - virtual void* findObject(const void* objectID) const = 0; + [[nodiscard]] virtual void* findObject(const void* objectID) const = 0; + /** + * Returns object attached with attachObject, and detaches it. This does not + * delete the object. + */ + [[nodiscard]] virtual void* detachObject(const void* objectID) = 0; + /** - * WARNING: this API does not call the cleanup function for legacy reasons. - * It also does not return void* for legacy reasons. If you need to detach - * an object and destroy it, there are two options: - * - if you can, don't call detachObject and instead wait for the destructor - * to clean it up. - * - manually retrieve and destruct the object (if multiple of your threads - * are accessing these APIs, you must guarantee that attachObject isn't - * called after findObject and before detachObject is called). + * Use the lock that this binder contains internally. For instance, this can + * be used to modify an attached object without needing to add an additional + * lock (though, that attached object must be retrieved before calling this + * method). Calling (most) IBinder methods inside this will deadlock. */ - virtual void detachObject(const void* objectID) = 0; + void withLock(const std::function<void()>& doWithLock); virtual BBinder* localBinder(); virtual BpBinder* remoteBinder(); diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index 883403ac59..b89714ad58 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -47,7 +47,8 @@ static void* kValue = static_cast<void*>(new bool{true}); void clean(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */}; static void attach(const sp<IBinder>& binder) { - binder->attachObject(kId, kValue, nullptr /*cookie*/, clean); + // can only attach once + CHECK_EQ(nullptr, binder->attachObject(kId, kValue, nullptr /*cookie*/, clean)); } static bool has(const sp<IBinder>& binder) { return binder != nullptr && binder->findObject(kId) == kValue; @@ -57,7 +58,6 @@ static bool has(const sp<IBinder>& binder) { namespace ABpBinderTag { -static std::mutex gLock; static const void* kId = "ABpBinder"; struct Value { wp<ABpBinder> binder; @@ -232,19 +232,14 @@ ABpBinder::ABpBinder(const ::android::sp<::android::IBinder>& binder) ABpBinder::~ABpBinder() {} void ABpBinder::onLastStrongRef(const void* id) { - { - std::lock_guard<std::mutex> lock(ABpBinderTag::gLock); - // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for - // the ABpBinder to be deleted. Since a strong reference to this ABpBinder object should no - // longer be able to exist at the time of this method call, there is no longer a need to - // recover it. - - ABpBinderTag::Value* value = - static_cast<ABpBinderTag::Value*>(remote()->findObject(ABpBinderTag::kId)); - if (value != nullptr) { - value->binder = nullptr; - } - } + // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for + // the ABpBinder to be deleted. Since a strong reference to this ABpBinder object should no + // longer be able to exist at the time of this method call, there is no longer a need to + // recover it. + + ABpBinderTag::Value* value = + static_cast<ABpBinderTag::Value*>(remote()->detachObject(ABpBinderTag::kId)); + if (value) ABpBinderTag::clean(ABpBinderTag::kId, value, nullptr /*cookie*/); BpRefBase::onLastStrongRef(id); } @@ -257,23 +252,28 @@ sp<AIBinder> ABpBinder::lookupOrCreateFromBinder(const ::android::sp<::android:: return static_cast<ABBinder*>(binder.get()); } - // The following code ensures that for a given binder object (remote or local), if it is not an - // ABBinder then at most one ABpBinder object exists in a given process representing it. - std::lock_guard<std::mutex> lock(ABpBinderTag::gLock); - - ABpBinderTag::Value* value = - static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId)); + auto* value = static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId)); if (value == nullptr) { value = new ABpBinderTag::Value; - binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value), nullptr /*cookie*/, - ABpBinderTag::clean); + auto oldValue = static_cast<ABpBinderTag::Value*>( + binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value), + nullptr /*cookie*/, ABpBinderTag::clean)); + + // allocated by another thread + if (oldValue) { + delete value; + value = oldValue; + } } - sp<ABpBinder> ret = value->binder.promote(); - if (ret == nullptr) { - ret = new ABpBinder(binder); - value->binder = ret; - } + sp<ABpBinder> ret; + binder->withLock([&]() { + ret = value->binder.promote(); + if (ret == nullptr) { + ret = sp<ABpBinder>::make(binder); + value->binder = ret; + } + }); return ret; } diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h index 22cacb4e08..f2c69b3191 100644 --- a/libs/binder/ndk/ibinder_internal.h +++ b/libs/binder/ndk/ibinder_internal.h @@ -105,6 +105,7 @@ struct ABpBinder : public AIBinder, public ::android::BpRefBase { ABpBinder* asABpBinder() override { return this; } private: + friend android::sp<ABpBinder>; explicit ABpBinder(const ::android::sp<::android::IBinder>& binder); }; diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs index 2a09afc6dc..f79b1b7023 100644 --- a/libs/binder/rust/src/binder.rs +++ b/libs/binder/rust/src/binder.rs @@ -50,7 +50,7 @@ pub type TransactionFlags = u32; /// interfaces) must implement this trait. /// /// This is equivalent `IInterface` in C++. -pub trait Interface: Send { +pub trait Interface: Send + Sync { /// Convert this binder object into a generic [`SpIBinder`] reference. fn as_binder(&self) -> SpIBinder { panic!("This object was not a Binder object and cannot be converted into an SpIBinder.") diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs index 5e324b3f5b..a0dfeecf43 100644 --- a/libs/binder/rust/src/native.rs +++ b/libs/binder/rust/src/native.rs @@ -51,6 +51,25 @@ pub struct Binder<T: Remotable> { /// to how `Box<T>` is `Send` if `T` is `Send`. unsafe impl<T: Remotable> Send for Binder<T> {} +/// # Safety +/// +/// A `Binder<T>` is a pair of unique owning pointers to two values: +/// * a C++ ABBinder which is thread-safe, i.e. `Send + Sync` +/// * a Rust object which implements `Remotable`; this trait requires `Send + Sync` +/// +/// `ABBinder` contains an immutable `mUserData` pointer, which is actually a +/// pointer to a boxed `T: Remotable`, which is `Sync`. `ABBinder` also contains +/// a mutable pointer to its class, but mutation of this field is controlled by +/// a mutex and it is only allowed to be set once, therefore we can concurrently +/// access this field safely. `ABBinder` inherits from `BBinder`, which is also +/// thread-safe. Thus `ABBinder` is thread-safe. +/// +/// Both pointers are unique (never escape the `Binder<T>` object and are not copied) +/// so we can essentially treat `Binder<T>` as a box-like containing the two objects; +/// the box-like object inherits `Sync` from the two inner values, similarly +/// to how `Box<T>` is `Sync` if `T` is `Sync`. +unsafe impl<T: Remotable> Sync for Binder<T> {} + impl<T: Remotable> Binder<T> { /// Create a new Binder remotable object with default stability /// diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs index e299963c9d..cdd7c081d0 100644 --- a/libs/binder/rust/src/proxy.rs +++ b/libs/binder/rust/src/proxy.rs @@ -48,9 +48,14 @@ impl fmt::Debug for SpIBinder { /// # Safety /// -/// An `SpIBinder` is a handle to a C++ IBinder, which is thread-safe +/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe unsafe impl Send for SpIBinder {} +/// # Safety +/// +/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe +unsafe impl Sync for SpIBinder {} + impl SpIBinder { /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer. /// @@ -448,9 +453,14 @@ impl fmt::Debug for WpIBinder { /// # Safety /// -/// A `WpIBinder` is a handle to a C++ IBinder, which is thread-safe. +/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe. unsafe impl Send for WpIBinder {} +/// # Safety +/// +/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe. +unsafe impl Sync for WpIBinder {} + impl WpIBinder { /// Create a new weak reference from an object that can be converted into a /// raw `AIBinder` pointer. diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index 1f844e1ee6..24afcf6632 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -77,14 +77,14 @@ cc_test { // unit test only, which can run on host and doesn't use /dev/binder cc_test { - name: "binderParcelTest", + name: "binderUnitTest", host_supported: true, target: { darwin: { enabled: false, }, }, - srcs: ["binderParcelTest.cpp"], + srcs: ["binderParcelUnitTest.cpp", "binderBinderUnitTest.cpp"], shared_libs: [ "libbinder", "libutils", diff --git a/libs/binder/tests/binderBinderUnitTest.cpp b/libs/binder/tests/binderBinderUnitTest.cpp new file mode 100644 index 0000000000..1be0c59c78 --- /dev/null +++ b/libs/binder/tests/binderBinderUnitTest.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <binder/Binder.h> +#include <binder/IBinder.h> +#include <gtest/gtest.h> + +using android::BBinder; +using android::OK; +using android::sp; + +const void* kObjectId1 = reinterpret_cast<const void*>(1); +const void* kObjectId2 = reinterpret_cast<const void*>(2); +void* kObject1 = reinterpret_cast<void*>(101); +void* kObject2 = reinterpret_cast<void*>(102); +void* kObject3 = reinterpret_cast<void*>(103); + +TEST(Binder, AttachObject) { + auto binder = sp<BBinder>::make(); + EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject1, nullptr, nullptr)); + EXPECT_EQ(nullptr, binder->attachObject(kObjectId2, kObject2, nullptr, nullptr)); + EXPECT_EQ(kObject1, binder->attachObject(kObjectId1, kObject3, nullptr, nullptr)); +} + +TEST(Binder, DetachObject) { + auto binder = sp<BBinder>::make(); + EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject1, nullptr, nullptr)); + EXPECT_EQ(kObject1, binder->detachObject(kObjectId1)); + EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject2, nullptr, nullptr)); +} diff --git a/libs/binder/tests/binderParcelTest.cpp b/libs/binder/tests/binderParcelUnitTest.cpp index 17642281c3..fb49d7a55a 100644 --- a/libs/binder/tests/binderParcelTest.cpp +++ b/libs/binder/tests/binderParcelUnitTest.cpp @@ -14,20 +14,21 @@ * limitations under the License. */ -#include <binder/Parcel.h> #include <binder/IPCThreadState.h> +#include <binder/Parcel.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; // 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) { +void parcelOpSameLength(const std::function<void(Parcel*)>& a, + const std::function<void(Parcel*)>& b) { Parcel p; a(&p); size_t end = p.dataPosition(); @@ -38,33 +39,30 @@ void parcelOpSameLength(const std::function<void(Parcel*)>& a, const std::functi TEST(Parcel, InverseInterfaceToken) { const String16 token = String16("asdf"); - parcelOpSameLength([&] (Parcel* p) { - p->writeInterfaceToken(token); - }, [&] (Parcel* p) { - EXPECT_TRUE(p->enforceInterface(token, IPCThreadState::self())); - }); + parcelOpSameLength([&](Parcel* p) { p->writeInterfaceToken(token); }, + [&](Parcel* p) { + EXPECT_TRUE(p->enforceInterface(token, IPCThreadState::self())); + }); } TEST(Parcel, Utf8FromUtf16Read) { const char* token = "asdf"; - parcelOpSameLength([&] (Parcel* p) { - p->writeString16(String16(token)); - }, [&] (Parcel* p) { - std::string s; - EXPECT_EQ(OK, p->readUtf8FromUtf16(&s)); - EXPECT_EQ(token, s); - }); + parcelOpSameLength([&](Parcel* p) { p->writeString16(String16(token)); }, + [&](Parcel* p) { + std::string s; + EXPECT_EQ(OK, p->readUtf8FromUtf16(&s)); + EXPECT_EQ(token, s); + }); } TEST(Parcel, Utf8AsUtf16Write) { std::string token = "asdf"; - parcelOpSameLength([&] (Parcel* p) { - p->writeUtf8AsUtf16(token); - }, [&] (Parcel* p) { - String16 s; - EXPECT_EQ(OK, p->readString16(&s)); - EXPECT_EQ(s, String16(token.c_str())); - }); + parcelOpSameLength([&](Parcel* p) { p->writeUtf8AsUtf16(token); }, + [&](Parcel* p) { + String16 s; + EXPECT_EQ(OK, p->readString16(&s)); + EXPECT_EQ(s, String16(token.c_str())); + }); } template <typename T> @@ -77,13 +75,12 @@ using copyWriteFunc = status_t (Parcel::*)(T in); template <typename T, typename WRITE_FUNC> void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, WRITE_FUNC w) { for (const T& value : ts) { - parcelOpSameLength([&] (Parcel* p) { - (*p.*w)(value); - }, [&] (Parcel* p) { - T outValue; - EXPECT_EQ(OK, (*p.*r)(&outValue)); - EXPECT_EQ(value, outValue); - }); + parcelOpSameLength([&](Parcel* p) { (*p.*w)(value); }, + [&](Parcel* p) { + T outValue; + EXPECT_EQ(OK, (*p.*r)(&outValue)); + EXPECT_EQ(value, outValue); + }); } } @@ -96,8 +93,8 @@ void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, copyWriteFunc<T> w) { readWriteInverse<T, copyWriteFunc<T>>(std::move(ts), r, w); } -#define TEST_READ_WRITE_INVERSE(type, name, ...) \ - TEST(Parcel, Inverse##name) { \ +#define TEST_READ_WRITE_INVERSE(type, name, ...) \ + TEST(Parcel, Inverse##name) { \ readWriteInverse<type>(__VA_ARGS__, &Parcel::read##name, &Parcel::write##name); \ } diff --git a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h index 626b7585f7..4a0aebac43 100644 --- a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h +++ b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h @@ -62,20 +62,22 @@ static const std::vector<std::function<void(FuzzedDataProvider*, IBinder*)>> gIB object = fdp->ConsumeIntegral<uint32_t>(); cleanup_cookie = fdp->ConsumeIntegral<uint32_t>(); IBinder::object_cleanup_func func = IBinder::object_cleanup_func(); - ibinder->attachObject(fdp->ConsumeBool() ? reinterpret_cast<void*>(&objectID) - : nullptr, - fdp->ConsumeBool() ? reinterpret_cast<void*>(&object) : nullptr, - fdp->ConsumeBool() ? reinterpret_cast<void*>(&cleanup_cookie) - : nullptr, - func); + (void)ibinder->attachObject(fdp->ConsumeBool() ? reinterpret_cast<void*>(&objectID) + : nullptr, + fdp->ConsumeBool() ? reinterpret_cast<void*>(&object) + : nullptr, + fdp->ConsumeBool() + ? reinterpret_cast<void*>(&cleanup_cookie) + : nullptr, + func); }, [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { uint32_t id = fdp->ConsumeIntegral<uint32_t>(); - ibinder->findObject(reinterpret_cast<void*>(&id)); + (void)ibinder->findObject(reinterpret_cast<void*>(&id)); }, [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { uint32_t id = fdp->ConsumeIntegral<uint32_t>(); - ibinder->detachObject(reinterpret_cast<void*>(&id)); + (void)ibinder->detachObject(reinterpret_cast<void*>(&id)); }, [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { uint32_t code = fdp->ConsumeIntegral<uint32_t>(); |