xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderRpcTestService.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include "binderRpcTestCommon.h"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker using namespace android;
20*38e8c45fSAndroid Build Coastguard Worker using android::binder::ReadFdToString;
21*38e8c45fSAndroid Build Coastguard Worker using android::binder::unique_fd;
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker class MyBinderRpcTestAndroid : public MyBinderRpcTestBase {
24*38e8c45fSAndroid Build Coastguard Worker public:
25*38e8c45fSAndroid Build Coastguard Worker     wp<RpcServer> server;
26*38e8c45fSAndroid Build Coastguard Worker 
countBinders(std::vector<int32_t> * out)27*38e8c45fSAndroid Build Coastguard Worker     Status countBinders(std::vector<int32_t>* out) override {
28*38e8c45fSAndroid Build Coastguard Worker         return countBindersImpl(server, out);
29*38e8c45fSAndroid Build Coastguard Worker     }
30*38e8c45fSAndroid Build Coastguard Worker 
die(bool cleanup)31*38e8c45fSAndroid Build Coastguard Worker     Status die(bool cleanup) override {
32*38e8c45fSAndroid Build Coastguard Worker         if (cleanup) {
33*38e8c45fSAndroid Build Coastguard Worker             exit(1);
34*38e8c45fSAndroid Build Coastguard Worker         } else {
35*38e8c45fSAndroid Build Coastguard Worker             _exit(1);
36*38e8c45fSAndroid Build Coastguard Worker         }
37*38e8c45fSAndroid Build Coastguard Worker     }
38*38e8c45fSAndroid Build Coastguard Worker 
scheduleShutdown()39*38e8c45fSAndroid Build Coastguard Worker     Status scheduleShutdown() override {
40*38e8c45fSAndroid Build Coastguard Worker         sp<RpcServer> strongServer = server.promote();
41*38e8c45fSAndroid Build Coastguard Worker         if (strongServer == nullptr) {
42*38e8c45fSAndroid Build Coastguard Worker             return Status::fromExceptionCode(Status::EX_NULL_POINTER);
43*38e8c45fSAndroid Build Coastguard Worker         }
44*38e8c45fSAndroid Build Coastguard Worker         RpcMaybeThread([=] {
45*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(!strongServer->shutdown(), "Could not shutdown");
46*38e8c45fSAndroid Build Coastguard Worker         }).detach();
47*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
48*38e8c45fSAndroid Build Coastguard Worker     }
49*38e8c45fSAndroid Build Coastguard Worker 
useKernelBinderCallingId()50*38e8c45fSAndroid Build Coastguard Worker     Status useKernelBinderCallingId() override {
51*38e8c45fSAndroid Build Coastguard Worker         // this is WRONG! It does not make sense when using RPC binder, and
52*38e8c45fSAndroid Build Coastguard Worker         // because it is SO wrong, and so much code calls this, it should abort!
53*38e8c45fSAndroid Build Coastguard Worker 
54*38e8c45fSAndroid Build Coastguard Worker         if constexpr (kEnableKernelIpc) {
55*38e8c45fSAndroid Build Coastguard Worker             (void)IPCThreadState::self()->getCallingPid();
56*38e8c45fSAndroid Build Coastguard Worker         }
57*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
58*38e8c45fSAndroid Build Coastguard Worker     }
59*38e8c45fSAndroid Build Coastguard Worker 
echoAsFile(const std::string & content,android::os::ParcelFileDescriptor * out)60*38e8c45fSAndroid Build Coastguard Worker     Status echoAsFile(const std::string& content, android::os::ParcelFileDescriptor* out) override {
61*38e8c45fSAndroid Build Coastguard Worker         out->reset(mockFileDescriptor(content));
62*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
63*38e8c45fSAndroid Build Coastguard Worker     }
64*38e8c45fSAndroid Build Coastguard Worker 
concatFiles(const std::vector<android::os::ParcelFileDescriptor> & files,android::os::ParcelFileDescriptor * out)65*38e8c45fSAndroid Build Coastguard Worker     Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& files,
66*38e8c45fSAndroid Build Coastguard Worker                        android::os::ParcelFileDescriptor* out) override {
67*38e8c45fSAndroid Build Coastguard Worker         std::string acc;
68*38e8c45fSAndroid Build Coastguard Worker         for (const auto& file : files) {
69*38e8c45fSAndroid Build Coastguard Worker             std::string result;
70*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(!ReadFdToString(file.get(), &result));
71*38e8c45fSAndroid Build Coastguard Worker             acc.append(result);
72*38e8c45fSAndroid Build Coastguard Worker         }
73*38e8c45fSAndroid Build Coastguard Worker         out->reset(mockFileDescriptor(acc));
74*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
75*38e8c45fSAndroid Build Coastguard Worker     }
76*38e8c45fSAndroid Build Coastguard Worker 
77*38e8c45fSAndroid Build Coastguard Worker     HandoffChannel<unique_fd> mFdChannel;
78*38e8c45fSAndroid Build Coastguard Worker 
blockingSendFdOneway(const android::os::ParcelFileDescriptor & fd)79*38e8c45fSAndroid Build Coastguard Worker     Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& fd) override {
80*38e8c45fSAndroid Build Coastguard Worker         mFdChannel.write(unique_fd(fcntl(fd.get(), F_DUPFD_CLOEXEC, 0)));
81*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
82*38e8c45fSAndroid Build Coastguard Worker     }
83*38e8c45fSAndroid Build Coastguard Worker 
blockingRecvFd(android::os::ParcelFileDescriptor * fd)84*38e8c45fSAndroid Build Coastguard Worker     Status blockingRecvFd(android::os::ParcelFileDescriptor* fd) override {
85*38e8c45fSAndroid Build Coastguard Worker         fd->reset(mFdChannel.read());
86*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
87*38e8c45fSAndroid Build Coastguard Worker     }
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker     HandoffChannel<int> mIntChannel;
90*38e8c45fSAndroid Build Coastguard Worker 
blockingSendIntOneway(int n)91*38e8c45fSAndroid Build Coastguard Worker     Status blockingSendIntOneway(int n) override {
92*38e8c45fSAndroid Build Coastguard Worker         mIntChannel.write(n);
93*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
94*38e8c45fSAndroid Build Coastguard Worker     }
95*38e8c45fSAndroid Build Coastguard Worker 
blockingRecvInt(int * n)96*38e8c45fSAndroid Build Coastguard Worker     Status blockingRecvInt(int* n) override {
97*38e8c45fSAndroid Build Coastguard Worker         *n = mIntChannel.read();
98*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
99*38e8c45fSAndroid Build Coastguard Worker     }
100*38e8c45fSAndroid Build Coastguard Worker };
101*38e8c45fSAndroid Build Coastguard Worker 
main(int argc,char * argv[])102*38e8c45fSAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
103*38e8c45fSAndroid Build Coastguard Worker     __android_log_set_logger(__android_log_stderr_logger);
104*38e8c45fSAndroid Build Coastguard Worker 
105*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(argc != 3, "Invalid number of arguments: %d", argc);
106*38e8c45fSAndroid Build Coastguard Worker     unique_fd writeEnd(atoi(argv[1]));
107*38e8c45fSAndroid Build Coastguard Worker     unique_fd readEnd(atoi(argv[2]));
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker     auto serverConfig = readFromFd<BinderRpcTestServerConfig>(readEnd);
110*38e8c45fSAndroid Build Coastguard Worker     auto socketType = static_cast<SocketType>(serverConfig.socketType);
111*38e8c45fSAndroid Build Coastguard Worker     auto rpcSecurity = static_cast<RpcSecurity>(serverConfig.rpcSecurity);
112*38e8c45fSAndroid Build Coastguard Worker 
113*38e8c45fSAndroid Build Coastguard Worker     std::vector<RpcSession::FileDescriptorTransportMode>
114*38e8c45fSAndroid Build Coastguard Worker             serverSupportedFileDescriptorTransportModes;
115*38e8c45fSAndroid Build Coastguard Worker     for (auto mode : serverConfig.serverSupportedFileDescriptorTransportModes) {
116*38e8c45fSAndroid Build Coastguard Worker         serverSupportedFileDescriptorTransportModes.push_back(
117*38e8c45fSAndroid Build Coastguard Worker                 static_cast<RpcSession::FileDescriptorTransportMode>(mode));
118*38e8c45fSAndroid Build Coastguard Worker     }
119*38e8c45fSAndroid Build Coastguard Worker 
120*38e8c45fSAndroid Build Coastguard Worker     auto certVerifier = std::make_shared<RpcCertificateVerifierSimple>();
121*38e8c45fSAndroid Build Coastguard Worker     sp<RpcServer> server = RpcServer::make(newTlsFactory(rpcSecurity, certVerifier));
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!server->setProtocolVersion(serverConfig.serverVersion));
124*38e8c45fSAndroid Build Coastguard Worker     server->setMaxThreads(serverConfig.numThreads);
125*38e8c45fSAndroid Build Coastguard Worker     server->setSupportedFileDescriptorTransportModes(serverSupportedFileDescriptorTransportModes);
126*38e8c45fSAndroid Build Coastguard Worker 
127*38e8c45fSAndroid Build Coastguard Worker     unsigned int outPort = 0;
128*38e8c45fSAndroid Build Coastguard Worker     unique_fd socketFd(serverConfig.socketFd);
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker     switch (socketType) {
131*38e8c45fSAndroid Build Coastguard Worker         case SocketType::PRECONNECTED:
132*38e8c45fSAndroid Build Coastguard Worker             [[fallthrough]];
133*38e8c45fSAndroid Build Coastguard Worker         case SocketType::UNIX:
134*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(OK != server->setupUnixDomainServer(serverConfig.addr.c_str()),
135*38e8c45fSAndroid Build Coastguard Worker                                 "%s", serverConfig.addr.c_str());
136*38e8c45fSAndroid Build Coastguard Worker             break;
137*38e8c45fSAndroid Build Coastguard Worker         case SocketType::UNIX_BOOTSTRAP:
138*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(OK !=
139*38e8c45fSAndroid Build Coastguard Worker                                 server->setupUnixDomainSocketBootstrapServer(std::move(socketFd)));
140*38e8c45fSAndroid Build Coastguard Worker             break;
141*38e8c45fSAndroid Build Coastguard Worker         case SocketType::UNIX_RAW:
142*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(OK != server->setupRawSocketServer(std::move(socketFd)));
143*38e8c45fSAndroid Build Coastguard Worker             break;
144*38e8c45fSAndroid Build Coastguard Worker         case SocketType::VSOCK:
145*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(OK !=
146*38e8c45fSAndroid Build Coastguard Worker                                         server->setupVsockServer(VMADDR_CID_LOCAL, VMADDR_PORT_ANY,
147*38e8c45fSAndroid Build Coastguard Worker                                                                  &outPort),
148*38e8c45fSAndroid Build Coastguard Worker                                 "Need `sudo modprobe vsock_loopback`?");
149*38e8c45fSAndroid Build Coastguard Worker             break;
150*38e8c45fSAndroid Build Coastguard Worker         case SocketType::INET: {
151*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(OK != server->setupInetServer(kLocalInetAddress, 0, &outPort));
152*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(0 == outPort);
153*38e8c45fSAndroid Build Coastguard Worker             break;
154*38e8c45fSAndroid Build Coastguard Worker         }
155*38e8c45fSAndroid Build Coastguard Worker         default:
156*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Unknown socket type");
157*38e8c45fSAndroid Build Coastguard Worker     }
158*38e8c45fSAndroid Build Coastguard Worker 
159*38e8c45fSAndroid Build Coastguard Worker     BinderRpcTestServerInfo serverInfo;
160*38e8c45fSAndroid Build Coastguard Worker     serverInfo.port = static_cast<int64_t>(outPort);
161*38e8c45fSAndroid Build Coastguard Worker     serverInfo.cert.data = server->getCertificate(RpcCertificateFormat::PEM);
162*38e8c45fSAndroid Build Coastguard Worker     writeToFd(writeEnd, serverInfo);
163*38e8c45fSAndroid Build Coastguard Worker     auto clientInfo = readFromFd<BinderRpcTestClientInfo>(readEnd);
164*38e8c45fSAndroid Build Coastguard Worker 
165*38e8c45fSAndroid Build Coastguard Worker     if (rpcSecurity == RpcSecurity::TLS) {
166*38e8c45fSAndroid Build Coastguard Worker         for (const auto& clientCert : clientInfo.certs) {
167*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(OK !=
168*38e8c45fSAndroid Build Coastguard Worker                                 certVerifier->addTrustedPeerCertificate(RpcCertificateFormat::PEM,
169*38e8c45fSAndroid Build Coastguard Worker                                                                         clientCert.data));
170*38e8c45fSAndroid Build Coastguard Worker         }
171*38e8c45fSAndroid Build Coastguard Worker     }
172*38e8c45fSAndroid Build Coastguard Worker 
173*38e8c45fSAndroid Build Coastguard Worker     server->setPerSessionRootObject([&](wp<RpcSession> session, const void* addrPtr, size_t len) {
174*38e8c45fSAndroid Build Coastguard Worker         {
175*38e8c45fSAndroid Build Coastguard Worker             sp<RpcSession> spSession = session.promote();
176*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(nullptr == spSession.get());
177*38e8c45fSAndroid Build Coastguard Worker         }
178*38e8c45fSAndroid Build Coastguard Worker 
179*38e8c45fSAndroid Build Coastguard Worker         // UNIX sockets with abstract addresses return
180*38e8c45fSAndroid Build Coastguard Worker         // sizeof(sa_family_t)==2 in addrlen
181*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(len < sizeof(sa_family_t));
182*38e8c45fSAndroid Build Coastguard Worker         const sockaddr* addr = reinterpret_cast<const sockaddr*>(addrPtr);
183*38e8c45fSAndroid Build Coastguard Worker         sp<MyBinderRpcTestAndroid> service = sp<MyBinderRpcTestAndroid>::make();
184*38e8c45fSAndroid Build Coastguard Worker         switch (addr->sa_family) {
185*38e8c45fSAndroid Build Coastguard Worker             case AF_UNIX:
186*38e8c45fSAndroid Build Coastguard Worker                 // nothing to save
187*38e8c45fSAndroid Build Coastguard Worker                 break;
188*38e8c45fSAndroid Build Coastguard Worker             case AF_VSOCK:
189*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL_IF(len != sizeof(sockaddr_vm));
190*38e8c45fSAndroid Build Coastguard Worker                 service->port = reinterpret_cast<const sockaddr_vm*>(addr)->svm_port;
191*38e8c45fSAndroid Build Coastguard Worker                 break;
192*38e8c45fSAndroid Build Coastguard Worker             case AF_INET:
193*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL_IF(len != sizeof(sockaddr_in));
194*38e8c45fSAndroid Build Coastguard Worker                 service->port = ntohs(reinterpret_cast<const sockaddr_in*>(addr)->sin_port);
195*38e8c45fSAndroid Build Coastguard Worker                 break;
196*38e8c45fSAndroid Build Coastguard Worker             case AF_INET6:
197*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL_IF(len != sizeof(sockaddr_in));
198*38e8c45fSAndroid Build Coastguard Worker                 service->port = ntohs(reinterpret_cast<const sockaddr_in6*>(addr)->sin6_port);
199*38e8c45fSAndroid Build Coastguard Worker                 break;
200*38e8c45fSAndroid Build Coastguard Worker             default:
201*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("Unrecognized address family %d", addr->sa_family);
202*38e8c45fSAndroid Build Coastguard Worker         }
203*38e8c45fSAndroid Build Coastguard Worker         service->server = server;
204*38e8c45fSAndroid Build Coastguard Worker         return service;
205*38e8c45fSAndroid Build Coastguard Worker     });
206*38e8c45fSAndroid Build Coastguard Worker 
207*38e8c45fSAndroid Build Coastguard Worker     server->join();
208*38e8c45fSAndroid Build Coastguard Worker 
209*38e8c45fSAndroid Build Coastguard Worker     // Another thread calls shutdown. Wait for it to complete.
210*38e8c45fSAndroid Build Coastguard Worker     (void)server->shutdown();
211*38e8c45fSAndroid Build Coastguard Worker 
212*38e8c45fSAndroid Build Coastguard Worker     return 0;
213*38e8c45fSAndroid Build Coastguard Worker }
214