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