summaryrefslogtreecommitdiff
path: root/libs/binder/RpcServer.cpp
diff options
context:
space:
mode:
author David Brazdil <dbrazdil@google.com> 2022-11-22 22:52:19 +0000
committer David Brazdil <dbrazdil@google.com> 2022-12-14 10:30:45 +0000
commita47dfdaf7b7e24cf87d7711fe70d8bc4ab1ddf45 (patch)
treeef6fcf0969261a75d8818e6ef7f3411904faa41b /libs/binder/RpcServer.cpp
parenta1cf02cf5095c7c93bbd9add5127e21309ea832a (diff)
rpc_binder: Specify CID for vsock RpcServer
Currently RpcServer only allows to start a server listening for connections from VMHOST_CID_ANY. This is not always desirable as clients may want to listen only for connections from specific CIDs, eg. only the host or only local. This can be partially solved by setting the bind CID of the virtual socket. The server can bind to VMADDR_CID_LOCAL for local interface only. VMADDR_CID_ANY same as its own CID will bind to the remote interface and accept connections from all clients. To this end, add a callback for filtering accepted connections in RpcServer. This may already be possible with per-session root object. However, the root object is selected very late, after initial negotiation with the client. For both performance and safety, add the callback immediately after accept() to reject the connection as early as possible. Bug: 245727626 Test: atest binderRpcTest Change-Id: I5b3e6fd5119c77ef8c5c4fbbfead9892c5de1a07
Diffstat (limited to 'libs/binder/RpcServer.cpp')
-rw-r--r--libs/binder/RpcServer.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 0820cd1d5c..fedc1d9593 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -70,11 +70,8 @@ status_t RpcServer::setupUnixDomainServer(const char* path) {
return setupSocketServer(UnixSocketAddress(path));
}
-status_t RpcServer::setupVsockServer(unsigned int port) {
- // realizing value w/ this type at compile time to avoid ubsan abort
- constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
-
- return setupSocketServer(VsockSocketAddress(kAnyCid, port));
+status_t RpcServer::setupVsockServer(unsigned int bindCid, unsigned int port) {
+ return setupSocketServer(VsockSocketAddress(bindCid, port));
}
status_t RpcServer::setupInetServer(const char* address, unsigned int port,
@@ -157,6 +154,12 @@ void RpcServer::setPerSessionRootObject(
mRootObjectFactory = std::move(makeObject);
}
+void RpcServer::setConnectionFilter(std::function<bool(const void*, size_t)>&& filter) {
+ RpcMutexLockGuard _l(mLock);
+ LOG_ALWAYS_FATAL_IF(mShutdownTrigger != nullptr, "Already joined");
+ mConnectionFilter = std::move(filter);
+}
+
sp<IBinder> RpcServer::getRootObject() {
RpcMutexLockGuard _l(mLock);
bool hasWeak = mRootObjectWeak.unsafe_get();
@@ -242,13 +245,19 @@ void RpcServer::join() {
if (mAcceptFn(*this, &clientSocket) != OK) {
continue;
}
+
+ LOG_RPC_DETAIL("accept on fd %d yields fd %d", mServer.fd.get(), clientSocket.fd.get());
+
if (getpeername(clientSocket.fd.get(), reinterpret_cast<sockaddr*>(addr.data()),
&addrLen)) {
ALOGE("Could not getpeername socket: %s", strerror(errno));
continue;
}
- LOG_RPC_DETAIL("accept on fd %d yields fd %d", mServer.fd.get(), clientSocket.fd.get());
+ if (mConnectionFilter != nullptr && !mConnectionFilter(addr.data(), addrLen)) {
+ ALOGE("Dropped client connection fd %d", clientSocket.fd.get());
+ continue;
+ }
{
RpcMutexLockGuard _l(mLock);