libbinder: fuzzer for RPC server
Fuzz sending arbitrary commands to a single connection on a single RPC
server.
Future considerations:
- support fuzzing multiple clients w/ multiple connections
- better way to wait for a service to shutdown
Bug: 182938024
Test: fuzzer can run for a few minutes w/o crashing
Change-Id: Ifc1da577208ba1effb02fa33b0b30fd5cfd98d9e
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 06c3a42..99c907a 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -118,30 +118,33 @@
}
void RpcServer::join() {
+ while (true) {
+ (void)acceptOne();
+ }
+}
+
+bool RpcServer::acceptOne() {
LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
+ LOG_ALWAYS_FATAL_IF(mServer.get() == -1, "RpcServer must be setup to join.");
+
+ unique_fd clientFd(
+ TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
+
+ if (clientFd < 0) {
+ ALOGE("Could not accept4 socket: %s", strerror(errno));
+ return false;
+ }
+ LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
+
{
std::lock_guard<std::mutex> _l(mLock);
- LOG_ALWAYS_FATAL_IF(mServer.get() == -1, "RpcServer must be setup to join.");
+ std::thread thread =
+ std::thread(&RpcServer::establishConnection, this,
+ std::move(sp<RpcServer>::fromExisting(this)), std::move(clientFd));
+ mConnectingThreads[thread.get_id()] = std::move(thread);
}
- while (true) {
- unique_fd clientFd(TEMP_FAILURE_RETRY(
- accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
-
- if (clientFd < 0) {
- ALOGE("Could not accept4 socket: %s", strerror(errno));
- continue;
- }
- LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
-
- {
- std::lock_guard<std::mutex> _l(mLock);
- std::thread thread =
- std::thread(&RpcServer::establishConnection, this,
- std::move(sp<RpcServer>::fromExisting(this)), std::move(clientFd));
- mConnectingThreads[thread.get_id()] = std::move(thread);
- }
- }
+ return true;
}
std::vector<sp<RpcSession>> RpcServer::listSessions() {
@@ -154,6 +157,11 @@
return sessions;
}
+size_t RpcServer::numUninitializedSessions() {
+ std::lock_guard<std::mutex> _l(mLock);
+ return mConnectingThreads.size();
+}
+
void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd) {
LOG_ALWAYS_FATAL_IF(this != server.get(), "Must pass same ownership object");