Merge changes Ifc1da577,Ide630e36,Ia215f1a0
* changes:
libbinder: fuzzer for RPC server
libbinder: RPC explicit connect thread ownership
libbinder: RPC cap transaction size at 100KB
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 501e281..95c4923 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1963,6 +1963,8 @@
RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
+ RunDumpsys("DUMPSYS", {"vcn_management"}, CommandOptions::WithTimeout(90).Build(),
+ SEC_TO_MSEC(10));
if (include_sensitive_info) {
// Carrier apps' services will be dumped below in dumpsys activity service all-non-platform.
RunDumpsys("DUMPSYS", {"carrier_config"}, CommandOptions::WithTimeout(90).Build(),
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 99c907a..3c63789 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -109,12 +109,21 @@
void RpcServer::setRootObject(const sp<IBinder>& binder) {
std::lock_guard<std::mutex> _l(mLock);
- mRootObject = binder;
+ mRootObjectWeak = mRootObject = binder;
+}
+
+void RpcServer::setRootObjectWeak(const wp<IBinder>& binder) {
+ std::lock_guard<std::mutex> _l(mLock);
+ mRootObject.clear();
+ mRootObjectWeak = binder;
}
sp<IBinder> RpcServer::getRootObject() {
std::lock_guard<std::mutex> _l(mLock);
- return mRootObject;
+ bool hasWeak = mRootObjectWeak.unsafe_get();
+ sp<IBinder> ret = mRootObjectWeak.promote();
+ ALOGW_IF(hasWeak && ret == nullptr, "RpcServer root object is freed, returning nullptr");
+ return ret;
}
void RpcServer::join() {
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index ec741a8..6e27540 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -90,8 +90,14 @@
/**
* The root object can be retrieved by any client, without any
* authentication. TODO(b/183988761)
+ *
+ * Holds a strong reference to the root object.
*/
void setRootObject(const sp<IBinder>& binder);
+ /**
+ * Holds a weak reference to the root object.
+ */
+ void setRootObjectWeak(const wp<IBinder>& binder);
sp<IBinder> getRootObject();
/**
@@ -134,6 +140,7 @@
std::mutex mLock; // for below
std::map<std::thread::id, std::thread> mConnectingThreads;
sp<IBinder> mRootObject;
+ wp<IBinder> mRootObjectWeak;
std::map<int32_t, sp<RpcSession>> mSessions;
int32_t mSessionIdCounter = 0;
};
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index b3ce744..260be57 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -929,6 +929,34 @@
}),
PrintSocketType);
+class BinderRpcServerRootObject : public ::testing::TestWithParam<std::tuple<bool, bool>> {};
+
+TEST_P(BinderRpcServerRootObject, WeakRootObject) {
+ using SetFn = std::function<void(RpcServer*, sp<IBinder>)>;
+ auto setRootObject = [](bool isStrong) -> SetFn {
+ return isStrong ? SetFn(&RpcServer::setRootObject) : SetFn(&RpcServer::setRootObjectWeak);
+ };
+
+ auto server = RpcServer::make();
+ auto [isStrong1, isStrong2] = GetParam();
+ auto binder1 = sp<BBinder>::make();
+ IBinder* binderRaw1 = binder1.get();
+ setRootObject(isStrong1)(server.get(), binder1);
+ EXPECT_EQ(binderRaw1, server->getRootObject());
+ binder1.clear();
+ EXPECT_EQ((isStrong1 ? binderRaw1 : nullptr), server->getRootObject());
+
+ auto binder2 = sp<BBinder>::make();
+ IBinder* binderRaw2 = binder2.get();
+ setRootObject(isStrong2)(server.get(), binder2);
+ EXPECT_EQ(binderRaw2, server->getRootObject());
+ binder2.clear();
+ EXPECT_EQ((isStrong2 ? binderRaw2 : nullptr), server->getRootObject());
+}
+
+INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcServerRootObject,
+ ::testing::Combine(::testing::Bool(), ::testing::Bool()));
+
} // namespace android
int main(int argc, char** argv) {