blob: b2b63e4bf35f7fd2873a25ac5113e95f343c2267 [file] [log] [blame]
Andrei Homescu2a298012022-06-15 01:08:54 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <BinderRpcTestClientInfo.h>
20#include <BinderRpcTestServerConfig.h>
21#include <BinderRpcTestServerInfo.h>
22#include <BnBinderRpcCallback.h>
23#include <BnBinderRpcSession.h>
24#include <BnBinderRpcTest.h>
Andrei Homescu9d8adb12022-08-02 04:38:30 +000025#include <binder/Binder.h>
26#include <binder/BpBinder.h>
27#include <binder/IPCThreadState.h>
28#include <binder/IServiceManager.h>
29#include <binder/RpcServer.h>
30#include <binder/RpcSession.h>
31#include <binder/RpcThreads.h>
32#include <binder/RpcTransport.h>
33#include <binder/RpcTransportRaw.h>
34#include <unistd.h>
35#include <cinttypes>
36#include <string>
37#include <vector>
38
Tomasz Wasilczykc2b71d52023-11-06 16:32:12 -080039#ifdef __ANDROID__
40#include <android-base/properties.h>
41#endif
42
Andrei Homescu9d8adb12022-08-02 04:38:30 +000043#ifndef __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +000044#include <android-base/file.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000045#include <android/binder_auto_utils.h>
46#include <android/binder_libbinder.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000047#include <binder/ProcessState.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000048#include <binder/RpcTlsTestUtils.h>
49#include <binder/RpcTlsUtils.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000050#include <binder/RpcTransportTls.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000051
52#include <signal.h>
53
David Brazdil21c887c2022-09-23 12:25:18 +010054#include "../OS.h" // for testing UnixBootstrap clients
Andrei Homescu2a298012022-06-15 01:08:54 +000055#include "../RpcSocketAddress.h" // for testing preconnected clients
Andrei Homescu2a298012022-06-15 01:08:54 +000056#include "../vm_sockets.h" // for VMADDR_*
Andrei Homescu9d8adb12022-08-02 04:38:30 +000057#endif // __TRUSTY__
58
59#include "../BuildFlags.h"
60#include "../FdTrigger.h"
61#include "../RpcState.h" // for debugging
Tomasz Wasilczyk3caae302023-10-12 20:57:02 +000062#include "format.h"
Andrei Homescu2a298012022-06-15 01:08:54 +000063#include "utils/Errors.h"
64
65namespace android {
66
67constexpr char kLocalInetAddress[] = "127.0.0.1";
68
69enum class RpcSecurity { RAW, TLS };
70
71static inline std::vector<RpcSecurity> RpcSecurityValues() {
72 return {RpcSecurity::RAW, RpcSecurity::TLS};
73}
74
Steven Moreland0884c552023-10-17 18:23:31 +000075static inline bool hasExperimentalRpc() {
76#ifdef __ANDROID__
77 return base::GetProperty("ro.build.version.codename", "") != "REL";
78#else
Steven Moreland687728e2023-10-28 01:07:40 +000079 return false;
Steven Moreland0884c552023-10-17 18:23:31 +000080#endif
81}
82
Andrei Homescu9d8adb12022-08-02 04:38:30 +000083static inline std::vector<uint32_t> testVersions() {
84 std::vector<uint32_t> versions;
85 for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
86 versions.push_back(i);
87 }
Steven Moreland0884c552023-10-17 18:23:31 +000088 if (hasExperimentalRpc()) {
89 versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
90 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +000091 return versions;
92}
93
94static inline std::string trustyIpcPort(uint32_t serverVersion) {
Tomasz Wasilczyk3caae302023-10-12 20:57:02 +000095 return std::format("com.android.trusty.binderRpcTestService.V{}", serverVersion);
Andrei Homescu9d8adb12022-08-02 04:38:30 +000096}
97
Andrei Homescu2a298012022-06-15 01:08:54 +000098enum class SocketType {
99 PRECONNECTED,
100 UNIX,
David Brazdil21c887c2022-09-23 12:25:18 +0100101 UNIX_BOOTSTRAP,
Alice Wang893a9912022-10-24 10:44:09 +0000102 UNIX_RAW,
Andrei Homescu2a298012022-06-15 01:08:54 +0000103 VSOCK,
104 INET,
Andrei Homescu68a55612022-08-02 01:25:15 +0000105 TIPC,
Andrei Homescu2a298012022-06-15 01:08:54 +0000106};
David Brazdil21c887c2022-09-23 12:25:18 +0100107
Andrei Homescu2a298012022-06-15 01:08:54 +0000108static inline std::string PrintToString(SocketType socketType) {
109 switch (socketType) {
110 case SocketType::PRECONNECTED:
111 return "preconnected_uds";
112 case SocketType::UNIX:
113 return "unix_domain_socket";
David Brazdil21c887c2022-09-23 12:25:18 +0100114 case SocketType::UNIX_BOOTSTRAP:
115 return "unix_domain_socket_bootstrap";
Alice Wang893a9912022-10-24 10:44:09 +0000116 case SocketType::UNIX_RAW:
117 return "raw_uds";
Andrei Homescu2a298012022-06-15 01:08:54 +0000118 case SocketType::VSOCK:
119 return "vm_socket";
120 case SocketType::INET:
121 return "inet_socket";
Andrei Homescu68a55612022-08-02 01:25:15 +0000122 case SocketType::TIPC:
123 return "trusty_ipc";
Andrei Homescu2a298012022-06-15 01:08:54 +0000124 default:
125 LOG_ALWAYS_FATAL("Unknown socket type");
126 return "";
127 }
128}
129
Andrei Homescu9a9b1b42022-10-14 01:40:59 +0000130static inline size_t epochMillis() {
131 using std::chrono::duration_cast;
132 using std::chrono::milliseconds;
133 using std::chrono::seconds;
134 using std::chrono::system_clock;
135 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
136}
137
Andrei Homescu2a298012022-06-15 01:08:54 +0000138struct BinderRpcOptions {
139 size_t numThreads = 1;
140 size_t numSessions = 1;
Steven Moreland67f85902023-03-15 01:13:49 +0000141 // right now, this can be empty, or length numSessions, where each value
142 // represents the info for the corresponding session, but we should
143 // probably switch this to be a list of sessions options so that other
144 // options can all be specified per session
145 std::vector<size_t> numIncomingConnectionsBySession = {};
Andrei Homescu2a298012022-06-15 01:08:54 +0000146 size_t numOutgoingConnections = SIZE_MAX;
147 RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
148 RpcSession::FileDescriptorTransportMode::NONE;
149 std::vector<RpcSession::FileDescriptorTransportMode>
150 serverSupportedFileDescriptorTransportModes = {
151 RpcSession::FileDescriptorTransportMode::NONE};
152
153 // If true, connection failures will result in `ProcessSession::sessions` being empty
154 // instead of a fatal error.
155 bool allowConnectFailure = false;
156};
157
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000158#ifndef __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000159static inline void writeString(android::base::borrowed_fd fd, std::string_view str) {
160 uint64_t length = str.length();
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700161 LOG_ALWAYS_FATAL_IF(!android::base::WriteFully(fd, &length, sizeof(length)));
162 LOG_ALWAYS_FATAL_IF(!android::base::WriteFully(fd, str.data(), str.length()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000163}
164
165static inline std::string readString(android::base::borrowed_fd fd) {
166 uint64_t length;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700167 LOG_ALWAYS_FATAL_IF(!android::base::ReadFully(fd, &length, sizeof(length)));
Andrei Homescu2a298012022-06-15 01:08:54 +0000168 std::string ret(length, '\0');
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700169 LOG_ALWAYS_FATAL_IF(!android::base::ReadFully(fd, ret.data(), length));
Andrei Homescu2a298012022-06-15 01:08:54 +0000170 return ret;
171}
172
173static inline void writeToFd(android::base::borrowed_fd fd, const Parcelable& parcelable) {
174 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700175 LOG_ALWAYS_FATAL_IF(OK != parcelable.writeToParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000176 writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
177}
178
179template <typename T>
180static inline T readFromFd(android::base::borrowed_fd fd) {
181 std::string data = readString(fd);
182 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700183 LOG_ALWAYS_FATAL_IF(OK !=
184 parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000185 T object;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700186 LOG_ALWAYS_FATAL_IF(OK != object.readFromParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000187 return object;
188}
189
Andrei Homescuf30148c2023-03-10 00:31:45 +0000190static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
Andrei Homescu2a298012022-06-15 01:08:54 +0000191 RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
192 std::unique_ptr<RpcAuth> auth = nullptr) {
193 switch (rpcSecurity) {
194 case RpcSecurity::RAW:
195 return RpcTransportCtxFactoryRaw::make();
196 case RpcSecurity::TLS: {
197 if (verifier == nullptr) {
198 verifier = std::make_shared<RpcCertificateVerifierSimple>();
199 }
200 if (auth == nullptr) {
201 auth = std::make_unique<RpcAuthSelfSigned>();
202 }
203 return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
204 }
205 default:
206 LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
207 }
208}
209
210// Create an FD that returns `contents` when read.
211static inline base::unique_fd mockFileDescriptor(std::string contents) {
212 android::base::unique_fd readFd, writeFd;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700213 LOG_ALWAYS_FATAL_IF(!android::base::Pipe(&readFd, &writeFd), "%s", strerror(errno));
Andrei Homescu2a298012022-06-15 01:08:54 +0000214 RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
215 signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
216 if (!WriteStringToFd(contents, writeFd)) {
217 int savedErrno = errno;
218 LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
219 strerror(savedErrno));
220 }
221 }).detach();
222 return readFd;
223}
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000224#endif // __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000225
Frederick Mayleb0221d12022-10-03 23:10:53 +0000226// A threadsafe channel where writes block until the value is read.
227template <typename T>
228class HandoffChannel {
229public:
230 void write(T v) {
231 {
232 RpcMutexUniqueLock lock(mMutex);
233 // Wait for space to send.
234 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
235 mValue.emplace(std::move(v));
236 }
237 mCvFull.notify_all();
238 RpcMutexUniqueLock lock(mMutex);
239 // Wait for it to be taken.
240 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
241 }
242
243 T read() {
244 RpcMutexUniqueLock lock(mMutex);
245 if (!mValue.has_value()) {
246 mCvFull.wait(lock, [&]() { return mValue.has_value(); });
247 }
248 T v = std::move(mValue.value());
249 mValue.reset();
250 lock.unlock();
251 mCvEmpty.notify_all();
252 return std::move(v);
253 }
254
255private:
256 RpcMutex mMutex;
257 RpcConditionVariable mCvEmpty;
258 RpcConditionVariable mCvFull;
259 std::optional<T> mValue;
260};
261
Andrei Homescu2a298012022-06-15 01:08:54 +0000262using android::binder::Status;
263
264class MyBinderRpcSession : public BnBinderRpcSession {
265public:
266 static std::atomic<int32_t> gNum;
267
268 MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
269 Status getName(std::string* name) override {
270 *name = mName;
271 return Status::ok();
272 }
273 ~MyBinderRpcSession() { gNum--; }
274
275private:
276 std::string mName;
277};
278
279class MyBinderRpcCallback : public BnBinderRpcCallback {
280 Status sendCallback(const std::string& value) {
281 RpcMutexUniqueLock _l(mMutex);
282 mValues.push_back(value);
283 _l.unlock();
284 mCv.notify_one();
285 return Status::ok();
286 }
287 Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
288
289public:
290 RpcMutex mMutex;
291 RpcConditionVariable mCv;
292 std::vector<std::string> mValues;
293};
294
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000295// Base class for all concrete implementations of MyBinderRpcTest.
296// Sub-classes that want to provide a full implementation should derive
297// from this class instead of MyBinderRpcTestDefault below so the compiler
298// checks that all methods are implemented.
299class MyBinderRpcTestBase : public BnBinderRpcTest {
Andrei Homescu2a298012022-06-15 01:08:54 +0000300public:
Andrei Homescu2a298012022-06-15 01:08:54 +0000301 int port = 0;
302
303 Status sendString(const std::string& str) override {
304 (void)str;
305 return Status::ok();
306 }
307 Status doubleString(const std::string& str, std::string* strstr) override {
308 *strstr = str + str;
309 return Status::ok();
310 }
311 Status getClientPort(int* out) override {
312 *out = port;
313 return Status::ok();
314 }
Andrei Homescu2a298012022-06-15 01:08:54 +0000315 Status getNullBinder(sp<IBinder>* out) override {
316 out->clear();
317 return Status::ok();
318 }
319 Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
320 if (binder == nullptr) {
321 std::cout << "Received null binder!" << std::endl;
322 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
323 }
324 *out = binder->pingBinder();
325 return Status::ok();
326 }
327 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
328 *out = binder;
329 return Status::ok();
330 }
331 static sp<IBinder> mHeldBinder;
332 Status holdBinder(const sp<IBinder>& binder) override {
333 mHeldBinder = binder;
334 return Status::ok();
335 }
336 Status getHeldBinder(sp<IBinder>* held) override {
337 *held = mHeldBinder;
338 return Status::ok();
339 }
340 Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
341 if (count <= 0) return Status::ok();
342 return binder->nestMe(this, count - 1);
343 }
344 Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
345 static sp<IBinder> binder = new BBinder;
346 *out = binder;
347 return Status::ok();
348 }
349 Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
350 *out = new MyBinderRpcSession(name);
351 return Status::ok();
352 }
353 Status getNumOpenSessions(int32_t* out) override {
354 *out = MyBinderRpcSession::gNum;
355 return Status::ok();
356 }
357
358 RpcMutex blockMutex;
359 Status lock() override {
360 blockMutex.lock();
361 return Status::ok();
362 }
363 Status unlockInMsAsync(int32_t ms) override {
364 usleep(ms * 1000);
365 blockMutex.unlock();
366 return Status::ok();
367 }
368 Status lockUnlock() override {
369 RpcMutexLockGuard _l(blockMutex);
370 return Status::ok();
371 }
372
373 Status sleepMs(int32_t ms) override {
374 usleep(ms * 1000);
375 return Status::ok();
376 }
377
378 Status sleepMsAsync(int32_t ms) override {
379 // In-process binder calls are asynchronous, but the call to this method
380 // is synchronous wrt its client. This in/out-process threading model
381 // diffentiation is a classic binder leaky abstraction (for better or
382 // worse) and is preserved here the way binder sockets plugs itself
383 // into BpBinder, as nothing is changed at the higher levels
384 // (IInterface) which result in this behavior.
385 return sleepMs(ms);
386 }
387
388 Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
389 const std::string& value) override {
390 if (callback == nullptr) {
391 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
392 }
393
394 if (delayed) {
395 RpcMaybeThread([=]() {
396 ALOGE("Executing delayed callback: '%s'", value.c_str());
397 Status status = doCallback(callback, oneway, false, value);
398 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
399 }).detach();
400 return Status::ok();
401 }
402
403 if (oneway) {
404 return callback->sendOnewayCallback(value);
405 }
406
407 return callback->sendCallback(value);
408 }
409
410 Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
411 const std::string& value) override {
412 return doCallback(callback, oneway, delayed, value);
413 }
414
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000415protected:
416 // Generic version of countBinders that works with both
417 // RpcServer and RpcServerTrusty
418 template <typename T>
419 Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
420 sp<T> spServer = server.promote();
421 if (spServer == nullptr) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000422 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
423 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000424 out->clear();
425 for (auto session : spServer->listSessions()) {
426 size_t count = session->state()->countBinders();
427 out->push_back(count);
Andrei Homescu2a298012022-06-15 01:08:54 +0000428 }
429 return Status::ok();
430 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000431};
Andrei Homescu2a298012022-06-15 01:08:54 +0000432
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000433// Default implementation of MyBinderRpcTest that can be used as-is
434// or derived from by classes that only want to implement a subset of
435// the unimplemented methods
436class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
437public:
438 Status countBinders(std::vector<int32_t>* /*out*/) override {
439 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000440 }
441
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000442 Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
443
444 Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
445
446 Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
447
448 Status echoAsFile(const std::string& /*content*/,
449 android::os::ParcelFileDescriptor* /*out*/) override {
450 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000451 }
Frederick Mayleb0221d12022-10-03 23:10:53 +0000452
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000453 Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
454 android::os::ParcelFileDescriptor* /*out*/) override {
455 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000456 }
457
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000458 Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
459 return Status::fromStatusT(UNKNOWN_TRANSACTION);
460 }
461
462 Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
463 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000464 }
Frederick Mayle96872592023-03-07 14:56:15 -0800465
466 Status blockingSendIntOneway(int /*n*/) override {
467 return Status::fromStatusT(UNKNOWN_TRANSACTION);
468 }
469
470 Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
Andrei Homescu2a298012022-06-15 01:08:54 +0000471};
472
473} // namespace android