blob: d0ec3fa5763693cfbfa39ac89d00e7ca4071add8 [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
39#ifndef __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +000040#include <android-base/file.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000041#include <android-base/properties.h>
42#include <android/binder_auto_utils.h>
43#include <android/binder_libbinder.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000044#include <binder/ProcessState.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000045#include <binder/RpcTlsTestUtils.h>
46#include <binder/RpcTlsUtils.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000047#include <binder/RpcTransportTls.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000048
49#include <signal.h>
50
David Brazdil21c887c2022-09-23 12:25:18 +010051#include "../OS.h" // for testing UnixBootstrap clients
Andrei Homescu2a298012022-06-15 01:08:54 +000052#include "../RpcSocketAddress.h" // for testing preconnected clients
Andrei Homescu2a298012022-06-15 01:08:54 +000053#include "../vm_sockets.h" // for VMADDR_*
Andrei Homescu9d8adb12022-08-02 04:38:30 +000054#endif // __TRUSTY__
55
56#include "../BuildFlags.h"
57#include "../FdTrigger.h"
58#include "../RpcState.h" // for debugging
Tomasz Wasilczyk3caae302023-10-12 20:57:02 +000059#include "format.h"
Andrei Homescu2a298012022-06-15 01:08:54 +000060#include "utils/Errors.h"
61
62namespace android {
63
64constexpr char kLocalInetAddress[] = "127.0.0.1";
65
66enum class RpcSecurity { RAW, TLS };
67
68static inline std::vector<RpcSecurity> RpcSecurityValues() {
69 return {RpcSecurity::RAW, RpcSecurity::TLS};
70}
71
Steven Moreland0884c552023-10-17 18:23:31 +000072static inline bool hasExperimentalRpc() {
73#ifdef __ANDROID__
74 return base::GetProperty("ro.build.version.codename", "") != "REL";
75#else
Steven Moreland687728e2023-10-28 01:07:40 +000076 return false;
Steven Moreland0884c552023-10-17 18:23:31 +000077#endif
78}
79
Andrei Homescu9d8adb12022-08-02 04:38:30 +000080static inline std::vector<uint32_t> testVersions() {
81 std::vector<uint32_t> versions;
82 for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
83 versions.push_back(i);
84 }
Steven Moreland0884c552023-10-17 18:23:31 +000085 if (hasExperimentalRpc()) {
86 versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
87 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +000088 return versions;
89}
90
91static inline std::string trustyIpcPort(uint32_t serverVersion) {
Tomasz Wasilczyk3caae302023-10-12 20:57:02 +000092 return std::format("com.android.trusty.binderRpcTestService.V{}", serverVersion);
Andrei Homescu9d8adb12022-08-02 04:38:30 +000093}
94
Andrei Homescu2a298012022-06-15 01:08:54 +000095enum class SocketType {
96 PRECONNECTED,
97 UNIX,
David Brazdil21c887c2022-09-23 12:25:18 +010098 UNIX_BOOTSTRAP,
Alice Wang893a9912022-10-24 10:44:09 +000099 UNIX_RAW,
Andrei Homescu2a298012022-06-15 01:08:54 +0000100 VSOCK,
101 INET,
Andrei Homescu68a55612022-08-02 01:25:15 +0000102 TIPC,
Andrei Homescu2a298012022-06-15 01:08:54 +0000103};
David Brazdil21c887c2022-09-23 12:25:18 +0100104
Andrei Homescu2a298012022-06-15 01:08:54 +0000105static inline std::string PrintToString(SocketType socketType) {
106 switch (socketType) {
107 case SocketType::PRECONNECTED:
108 return "preconnected_uds";
109 case SocketType::UNIX:
110 return "unix_domain_socket";
David Brazdil21c887c2022-09-23 12:25:18 +0100111 case SocketType::UNIX_BOOTSTRAP:
112 return "unix_domain_socket_bootstrap";
Alice Wang893a9912022-10-24 10:44:09 +0000113 case SocketType::UNIX_RAW:
114 return "raw_uds";
Andrei Homescu2a298012022-06-15 01:08:54 +0000115 case SocketType::VSOCK:
116 return "vm_socket";
117 case SocketType::INET:
118 return "inet_socket";
Andrei Homescu68a55612022-08-02 01:25:15 +0000119 case SocketType::TIPC:
120 return "trusty_ipc";
Andrei Homescu2a298012022-06-15 01:08:54 +0000121 default:
122 LOG_ALWAYS_FATAL("Unknown socket type");
123 return "";
124 }
125}
126
Andrei Homescu9a9b1b42022-10-14 01:40:59 +0000127static inline size_t epochMillis() {
128 using std::chrono::duration_cast;
129 using std::chrono::milliseconds;
130 using std::chrono::seconds;
131 using std::chrono::system_clock;
132 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
133}
134
Andrei Homescu2a298012022-06-15 01:08:54 +0000135struct BinderRpcOptions {
136 size_t numThreads = 1;
137 size_t numSessions = 1;
Steven Moreland67f85902023-03-15 01:13:49 +0000138 // right now, this can be empty, or length numSessions, where each value
139 // represents the info for the corresponding session, but we should
140 // probably switch this to be a list of sessions options so that other
141 // options can all be specified per session
142 std::vector<size_t> numIncomingConnectionsBySession = {};
Andrei Homescu2a298012022-06-15 01:08:54 +0000143 size_t numOutgoingConnections = SIZE_MAX;
144 RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
145 RpcSession::FileDescriptorTransportMode::NONE;
146 std::vector<RpcSession::FileDescriptorTransportMode>
147 serverSupportedFileDescriptorTransportModes = {
148 RpcSession::FileDescriptorTransportMode::NONE};
149
150 // If true, connection failures will result in `ProcessSession::sessions` being empty
151 // instead of a fatal error.
152 bool allowConnectFailure = false;
153};
154
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000155#ifndef __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000156static inline void writeString(android::base::borrowed_fd fd, std::string_view str) {
157 uint64_t length = str.length();
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700158 LOG_ALWAYS_FATAL_IF(!android::base::WriteFully(fd, &length, sizeof(length)));
159 LOG_ALWAYS_FATAL_IF(!android::base::WriteFully(fd, str.data(), str.length()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000160}
161
162static inline std::string readString(android::base::borrowed_fd fd) {
163 uint64_t length;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700164 LOG_ALWAYS_FATAL_IF(!android::base::ReadFully(fd, &length, sizeof(length)));
Andrei Homescu2a298012022-06-15 01:08:54 +0000165 std::string ret(length, '\0');
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700166 LOG_ALWAYS_FATAL_IF(!android::base::ReadFully(fd, ret.data(), length));
Andrei Homescu2a298012022-06-15 01:08:54 +0000167 return ret;
168}
169
170static inline void writeToFd(android::base::borrowed_fd fd, const Parcelable& parcelable) {
171 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700172 LOG_ALWAYS_FATAL_IF(OK != parcelable.writeToParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000173 writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
174}
175
176template <typename T>
177static inline T readFromFd(android::base::borrowed_fd fd) {
178 std::string data = readString(fd);
179 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700180 LOG_ALWAYS_FATAL_IF(OK !=
181 parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000182 T object;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700183 LOG_ALWAYS_FATAL_IF(OK != object.readFromParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000184 return object;
185}
186
Andrei Homescuf30148c2023-03-10 00:31:45 +0000187static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
Andrei Homescu2a298012022-06-15 01:08:54 +0000188 RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
189 std::unique_ptr<RpcAuth> auth = nullptr) {
190 switch (rpcSecurity) {
191 case RpcSecurity::RAW:
192 return RpcTransportCtxFactoryRaw::make();
193 case RpcSecurity::TLS: {
194 if (verifier == nullptr) {
195 verifier = std::make_shared<RpcCertificateVerifierSimple>();
196 }
197 if (auth == nullptr) {
198 auth = std::make_unique<RpcAuthSelfSigned>();
199 }
200 return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
201 }
202 default:
203 LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
204 }
205}
206
207// Create an FD that returns `contents` when read.
208static inline base::unique_fd mockFileDescriptor(std::string contents) {
209 android::base::unique_fd readFd, writeFd;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700210 LOG_ALWAYS_FATAL_IF(!android::base::Pipe(&readFd, &writeFd), "%s", strerror(errno));
Andrei Homescu2a298012022-06-15 01:08:54 +0000211 RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
212 signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
213 if (!WriteStringToFd(contents, writeFd)) {
214 int savedErrno = errno;
215 LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
216 strerror(savedErrno));
217 }
218 }).detach();
219 return readFd;
220}
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000221#endif // __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000222
Frederick Mayleb0221d12022-10-03 23:10:53 +0000223// A threadsafe channel where writes block until the value is read.
224template <typename T>
225class HandoffChannel {
226public:
227 void write(T v) {
228 {
229 RpcMutexUniqueLock lock(mMutex);
230 // Wait for space to send.
231 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
232 mValue.emplace(std::move(v));
233 }
234 mCvFull.notify_all();
235 RpcMutexUniqueLock lock(mMutex);
236 // Wait for it to be taken.
237 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
238 }
239
240 T read() {
241 RpcMutexUniqueLock lock(mMutex);
242 if (!mValue.has_value()) {
243 mCvFull.wait(lock, [&]() { return mValue.has_value(); });
244 }
245 T v = std::move(mValue.value());
246 mValue.reset();
247 lock.unlock();
248 mCvEmpty.notify_all();
249 return std::move(v);
250 }
251
252private:
253 RpcMutex mMutex;
254 RpcConditionVariable mCvEmpty;
255 RpcConditionVariable mCvFull;
256 std::optional<T> mValue;
257};
258
Andrei Homescu2a298012022-06-15 01:08:54 +0000259using android::binder::Status;
260
261class MyBinderRpcSession : public BnBinderRpcSession {
262public:
263 static std::atomic<int32_t> gNum;
264
265 MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
266 Status getName(std::string* name) override {
267 *name = mName;
268 return Status::ok();
269 }
270 ~MyBinderRpcSession() { gNum--; }
271
272private:
273 std::string mName;
274};
275
276class MyBinderRpcCallback : public BnBinderRpcCallback {
277 Status sendCallback(const std::string& value) {
278 RpcMutexUniqueLock _l(mMutex);
279 mValues.push_back(value);
280 _l.unlock();
281 mCv.notify_one();
282 return Status::ok();
283 }
284 Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
285
286public:
287 RpcMutex mMutex;
288 RpcConditionVariable mCv;
289 std::vector<std::string> mValues;
290};
291
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000292// Base class for all concrete implementations of MyBinderRpcTest.
293// Sub-classes that want to provide a full implementation should derive
294// from this class instead of MyBinderRpcTestDefault below so the compiler
295// checks that all methods are implemented.
296class MyBinderRpcTestBase : public BnBinderRpcTest {
Andrei Homescu2a298012022-06-15 01:08:54 +0000297public:
Andrei Homescu2a298012022-06-15 01:08:54 +0000298 int port = 0;
299
300 Status sendString(const std::string& str) override {
301 (void)str;
302 return Status::ok();
303 }
304 Status doubleString(const std::string& str, std::string* strstr) override {
305 *strstr = str + str;
306 return Status::ok();
307 }
308 Status getClientPort(int* out) override {
309 *out = port;
310 return Status::ok();
311 }
Andrei Homescu2a298012022-06-15 01:08:54 +0000312 Status getNullBinder(sp<IBinder>* out) override {
313 out->clear();
314 return Status::ok();
315 }
316 Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
317 if (binder == nullptr) {
318 std::cout << "Received null binder!" << std::endl;
319 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
320 }
321 *out = binder->pingBinder();
322 return Status::ok();
323 }
324 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
325 *out = binder;
326 return Status::ok();
327 }
328 static sp<IBinder> mHeldBinder;
329 Status holdBinder(const sp<IBinder>& binder) override {
330 mHeldBinder = binder;
331 return Status::ok();
332 }
333 Status getHeldBinder(sp<IBinder>* held) override {
334 *held = mHeldBinder;
335 return Status::ok();
336 }
337 Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
338 if (count <= 0) return Status::ok();
339 return binder->nestMe(this, count - 1);
340 }
341 Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
342 static sp<IBinder> binder = new BBinder;
343 *out = binder;
344 return Status::ok();
345 }
346 Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
347 *out = new MyBinderRpcSession(name);
348 return Status::ok();
349 }
350 Status getNumOpenSessions(int32_t* out) override {
351 *out = MyBinderRpcSession::gNum;
352 return Status::ok();
353 }
354
355 RpcMutex blockMutex;
356 Status lock() override {
357 blockMutex.lock();
358 return Status::ok();
359 }
360 Status unlockInMsAsync(int32_t ms) override {
361 usleep(ms * 1000);
362 blockMutex.unlock();
363 return Status::ok();
364 }
365 Status lockUnlock() override {
366 RpcMutexLockGuard _l(blockMutex);
367 return Status::ok();
368 }
369
370 Status sleepMs(int32_t ms) override {
371 usleep(ms * 1000);
372 return Status::ok();
373 }
374
375 Status sleepMsAsync(int32_t ms) override {
376 // In-process binder calls are asynchronous, but the call to this method
377 // is synchronous wrt its client. This in/out-process threading model
378 // diffentiation is a classic binder leaky abstraction (for better or
379 // worse) and is preserved here the way binder sockets plugs itself
380 // into BpBinder, as nothing is changed at the higher levels
381 // (IInterface) which result in this behavior.
382 return sleepMs(ms);
383 }
384
385 Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
386 const std::string& value) override {
387 if (callback == nullptr) {
388 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
389 }
390
391 if (delayed) {
392 RpcMaybeThread([=]() {
393 ALOGE("Executing delayed callback: '%s'", value.c_str());
394 Status status = doCallback(callback, oneway, false, value);
395 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
396 }).detach();
397 return Status::ok();
398 }
399
400 if (oneway) {
401 return callback->sendOnewayCallback(value);
402 }
403
404 return callback->sendCallback(value);
405 }
406
407 Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
408 const std::string& value) override {
409 return doCallback(callback, oneway, delayed, value);
410 }
411
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000412protected:
413 // Generic version of countBinders that works with both
414 // RpcServer and RpcServerTrusty
415 template <typename T>
416 Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
417 sp<T> spServer = server.promote();
418 if (spServer == nullptr) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000419 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
420 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000421 out->clear();
422 for (auto session : spServer->listSessions()) {
423 size_t count = session->state()->countBinders();
424 out->push_back(count);
Andrei Homescu2a298012022-06-15 01:08:54 +0000425 }
426 return Status::ok();
427 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000428};
Andrei Homescu2a298012022-06-15 01:08:54 +0000429
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000430// Default implementation of MyBinderRpcTest that can be used as-is
431// or derived from by classes that only want to implement a subset of
432// the unimplemented methods
433class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
434public:
435 Status countBinders(std::vector<int32_t>* /*out*/) override {
436 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000437 }
438
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000439 Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
440
441 Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
442
443 Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
444
445 Status echoAsFile(const std::string& /*content*/,
446 android::os::ParcelFileDescriptor* /*out*/) override {
447 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000448 }
Frederick Mayleb0221d12022-10-03 23:10:53 +0000449
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000450 Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
451 android::os::ParcelFileDescriptor* /*out*/) override {
452 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000453 }
454
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000455 Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
456 return Status::fromStatusT(UNKNOWN_TRANSACTION);
457 }
458
459 Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
460 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000461 }
Frederick Mayle96872592023-03-07 14:56:15 -0800462
463 Status blockingSendIntOneway(int /*n*/) override {
464 return Status::fromStatusT(UNKNOWN_TRANSACTION);
465 }
466
467 Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
Andrei Homescu2a298012022-06-15 01:08:54 +0000468};
469
470} // namespace android