blob: a55edd273e1bc61ce64302af9ba5d47b5e3f4a55 [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/binder_auto_utils.h>
45#include <android/binder_libbinder.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000046#include <binder/ProcessState.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000047#include <binder/RpcTlsTestUtils.h>
48#include <binder/RpcTlsUtils.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000049#include <binder/RpcTransportTls.h>
Andrei Homescu2a298012022-06-15 01:08:54 +000050
51#include <signal.h>
52
David Brazdil21c887c2022-09-23 12:25:18 +010053#include "../OS.h" // for testing UnixBootstrap clients
Andrei Homescu2a298012022-06-15 01:08:54 +000054#include "../RpcSocketAddress.h" // for testing preconnected clients
Andrei Homescu2a298012022-06-15 01:08:54 +000055#include "../vm_sockets.h" // for VMADDR_*
Andrei Homescu9d8adb12022-08-02 04:38:30 +000056#endif // __TRUSTY__
57
58#include "../BuildFlags.h"
59#include "../FdTrigger.h"
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -070060#include "../FdUtils.h"
Andrei Homescu9d8adb12022-08-02 04:38:30 +000061#include "../RpcState.h" // for debugging
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -070062#include "FileUtils.h"
Tomasz Wasilczyk3caae302023-10-12 20:57:02 +000063#include "format.h"
Andrei Homescu2a298012022-06-15 01:08:54 +000064#include "utils/Errors.h"
65
66namespace android {
67
68constexpr char kLocalInetAddress[] = "127.0.0.1";
69
70enum class RpcSecurity { RAW, TLS };
71
72static inline std::vector<RpcSecurity> RpcSecurityValues() {
73 return {RpcSecurity::RAW, RpcSecurity::TLS};
74}
75
Steven Moreland0884c552023-10-17 18:23:31 +000076static inline bool hasExperimentalRpc() {
77#ifdef __ANDROID__
78 return base::GetProperty("ro.build.version.codename", "") != "REL";
79#else
Steven Moreland687728e2023-10-28 01:07:40 +000080 return false;
Steven Moreland0884c552023-10-17 18:23:31 +000081#endif
82}
83
Andrei Homescu9d8adb12022-08-02 04:38:30 +000084static inline std::vector<uint32_t> testVersions() {
85 std::vector<uint32_t> versions;
86 for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
87 versions.push_back(i);
88 }
Steven Moreland0884c552023-10-17 18:23:31 +000089 if (hasExperimentalRpc()) {
90 versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
91 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +000092 return versions;
93}
94
95static inline std::string trustyIpcPort(uint32_t serverVersion) {
Tomasz Wasilczyk3caae302023-10-12 20:57:02 +000096 return std::format("com.android.trusty.binderRpcTestService.V{}", serverVersion);
Andrei Homescu9d8adb12022-08-02 04:38:30 +000097}
98
Andrei Homescu2a298012022-06-15 01:08:54 +000099enum class SocketType {
100 PRECONNECTED,
101 UNIX,
David Brazdil21c887c2022-09-23 12:25:18 +0100102 UNIX_BOOTSTRAP,
Alice Wang893a9912022-10-24 10:44:09 +0000103 UNIX_RAW,
Andrei Homescu2a298012022-06-15 01:08:54 +0000104 VSOCK,
105 INET,
Andrei Homescu68a55612022-08-02 01:25:15 +0000106 TIPC,
Andrei Homescu2a298012022-06-15 01:08:54 +0000107};
David Brazdil21c887c2022-09-23 12:25:18 +0100108
Andrei Homescu2a298012022-06-15 01:08:54 +0000109static inline std::string PrintToString(SocketType socketType) {
110 switch (socketType) {
111 case SocketType::PRECONNECTED:
112 return "preconnected_uds";
113 case SocketType::UNIX:
114 return "unix_domain_socket";
David Brazdil21c887c2022-09-23 12:25:18 +0100115 case SocketType::UNIX_BOOTSTRAP:
116 return "unix_domain_socket_bootstrap";
Alice Wang893a9912022-10-24 10:44:09 +0000117 case SocketType::UNIX_RAW:
118 return "raw_uds";
Andrei Homescu2a298012022-06-15 01:08:54 +0000119 case SocketType::VSOCK:
120 return "vm_socket";
121 case SocketType::INET:
122 return "inet_socket";
Andrei Homescu68a55612022-08-02 01:25:15 +0000123 case SocketType::TIPC:
124 return "trusty_ipc";
Andrei Homescu2a298012022-06-15 01:08:54 +0000125 default:
126 LOG_ALWAYS_FATAL("Unknown socket type");
127 return "";
128 }
129}
130
Andrei Homescu9a9b1b42022-10-14 01:40:59 +0000131static inline size_t epochMillis() {
132 using std::chrono::duration_cast;
133 using std::chrono::milliseconds;
134 using std::chrono::seconds;
135 using std::chrono::system_clock;
136 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
137}
138
Andrei Homescu2a298012022-06-15 01:08:54 +0000139struct BinderRpcOptions {
140 size_t numThreads = 1;
141 size_t numSessions = 1;
Steven Moreland67f85902023-03-15 01:13:49 +0000142 // right now, this can be empty, or length numSessions, where each value
143 // represents the info for the corresponding session, but we should
144 // probably switch this to be a list of sessions options so that other
145 // options can all be specified per session
146 std::vector<size_t> numIncomingConnectionsBySession = {};
Andrei Homescu2a298012022-06-15 01:08:54 +0000147 size_t numOutgoingConnections = SIZE_MAX;
148 RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
149 RpcSession::FileDescriptorTransportMode::NONE;
150 std::vector<RpcSession::FileDescriptorTransportMode>
151 serverSupportedFileDescriptorTransportModes = {
152 RpcSession::FileDescriptorTransportMode::NONE};
153
154 // If true, connection failures will result in `ProcessSession::sessions` being empty
155 // instead of a fatal error.
156 bool allowConnectFailure = false;
157};
158
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000159#ifndef __TRUSTY__
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700160static inline void writeString(binder::borrowed_fd fd, std::string_view str) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000161 uint64_t length = str.length();
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700162 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, &length, sizeof(length)));
163 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, str.data(), str.length()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000164}
165
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700166static inline std::string readString(binder::borrowed_fd fd) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000167 uint64_t length;
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700168 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, &length, sizeof(length)));
Andrei Homescu2a298012022-06-15 01:08:54 +0000169 std::string ret(length, '\0');
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700170 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, ret.data(), length));
Andrei Homescu2a298012022-06-15 01:08:54 +0000171 return ret;
172}
173
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700174static inline void writeToFd(binder::borrowed_fd fd, const Parcelable& parcelable) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000175 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700176 LOG_ALWAYS_FATAL_IF(OK != parcelable.writeToParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000177 writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
178}
179
180template <typename T>
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700181static inline T readFromFd(binder::borrowed_fd fd) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000182 std::string data = readString(fd);
183 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700184 LOG_ALWAYS_FATAL_IF(OK !=
185 parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000186 T object;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700187 LOG_ALWAYS_FATAL_IF(OK != object.readFromParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000188 return object;
189}
190
Andrei Homescuf30148c2023-03-10 00:31:45 +0000191static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
Andrei Homescu2a298012022-06-15 01:08:54 +0000192 RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
193 std::unique_ptr<RpcAuth> auth = nullptr) {
194 switch (rpcSecurity) {
195 case RpcSecurity::RAW:
196 return RpcTransportCtxFactoryRaw::make();
197 case RpcSecurity::TLS: {
198 if (verifier == nullptr) {
199 verifier = std::make_shared<RpcCertificateVerifierSimple>();
200 }
201 if (auth == nullptr) {
202 auth = std::make_unique<RpcAuthSelfSigned>();
203 }
204 return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
205 }
206 default:
207 LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
208 }
209}
210
211// Create an FD that returns `contents` when read.
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700212static inline binder::unique_fd mockFileDescriptor(std::string contents) {
213 binder::unique_fd readFd, writeFd;
214 LOG_ALWAYS_FATAL_IF(!binder::Pipe(&readFd, &writeFd), "%s", strerror(errno));
Andrei Homescu2a298012022-06-15 01:08:54 +0000215 RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
216 signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700217 if (!android::binder::WriteStringToFd(contents, writeFd)) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000218 int savedErrno = errno;
219 LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
220 strerror(savedErrno));
221 }
222 }).detach();
223 return readFd;
224}
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000225#endif // __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000226
Frederick Mayleb0221d12022-10-03 23:10:53 +0000227// A threadsafe channel where writes block until the value is read.
228template <typename T>
229class HandoffChannel {
230public:
231 void write(T v) {
232 {
233 RpcMutexUniqueLock lock(mMutex);
234 // Wait for space to send.
235 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
236 mValue.emplace(std::move(v));
237 }
238 mCvFull.notify_all();
239 RpcMutexUniqueLock lock(mMutex);
240 // Wait for it to be taken.
241 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
242 }
243
244 T read() {
245 RpcMutexUniqueLock lock(mMutex);
246 if (!mValue.has_value()) {
247 mCvFull.wait(lock, [&]() { return mValue.has_value(); });
248 }
249 T v = std::move(mValue.value());
250 mValue.reset();
251 lock.unlock();
252 mCvEmpty.notify_all();
253 return std::move(v);
254 }
255
256private:
257 RpcMutex mMutex;
258 RpcConditionVariable mCvEmpty;
259 RpcConditionVariable mCvFull;
260 std::optional<T> mValue;
261};
262
Andrei Homescu2a298012022-06-15 01:08:54 +0000263using android::binder::Status;
264
265class MyBinderRpcSession : public BnBinderRpcSession {
266public:
267 static std::atomic<int32_t> gNum;
268
269 MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
270 Status getName(std::string* name) override {
271 *name = mName;
272 return Status::ok();
273 }
274 ~MyBinderRpcSession() { gNum--; }
275
276private:
277 std::string mName;
278};
279
280class MyBinderRpcCallback : public BnBinderRpcCallback {
281 Status sendCallback(const std::string& value) {
282 RpcMutexUniqueLock _l(mMutex);
283 mValues.push_back(value);
284 _l.unlock();
285 mCv.notify_one();
286 return Status::ok();
287 }
288 Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
289
290public:
291 RpcMutex mMutex;
292 RpcConditionVariable mCv;
293 std::vector<std::string> mValues;
294};
295
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000296// Base class for all concrete implementations of MyBinderRpcTest.
297// Sub-classes that want to provide a full implementation should derive
298// from this class instead of MyBinderRpcTestDefault below so the compiler
299// checks that all methods are implemented.
300class MyBinderRpcTestBase : public BnBinderRpcTest {
Andrei Homescu2a298012022-06-15 01:08:54 +0000301public:
Andrei Homescu2a298012022-06-15 01:08:54 +0000302 int port = 0;
303
304 Status sendString(const std::string& str) override {
305 (void)str;
306 return Status::ok();
307 }
308 Status doubleString(const std::string& str, std::string* strstr) override {
309 *strstr = str + str;
310 return Status::ok();
311 }
312 Status getClientPort(int* out) override {
313 *out = port;
314 return Status::ok();
315 }
Andrei Homescu2a298012022-06-15 01:08:54 +0000316 Status getNullBinder(sp<IBinder>* out) override {
317 out->clear();
318 return Status::ok();
319 }
320 Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
321 if (binder == nullptr) {
322 std::cout << "Received null binder!" << std::endl;
323 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
324 }
325 *out = binder->pingBinder();
326 return Status::ok();
327 }
328 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
329 *out = binder;
330 return Status::ok();
331 }
332 static sp<IBinder> mHeldBinder;
333 Status holdBinder(const sp<IBinder>& binder) override {
334 mHeldBinder = binder;
335 return Status::ok();
336 }
337 Status getHeldBinder(sp<IBinder>* held) override {
338 *held = mHeldBinder;
339 return Status::ok();
340 }
341 Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
342 if (count <= 0) return Status::ok();
343 return binder->nestMe(this, count - 1);
344 }
345 Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
346 static sp<IBinder> binder = new BBinder;
347 *out = binder;
348 return Status::ok();
349 }
350 Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
351 *out = new MyBinderRpcSession(name);
352 return Status::ok();
353 }
354 Status getNumOpenSessions(int32_t* out) override {
355 *out = MyBinderRpcSession::gNum;
356 return Status::ok();
357 }
358
359 RpcMutex blockMutex;
360 Status lock() override {
361 blockMutex.lock();
362 return Status::ok();
363 }
364 Status unlockInMsAsync(int32_t ms) override {
365 usleep(ms * 1000);
366 blockMutex.unlock();
367 return Status::ok();
368 }
369 Status lockUnlock() override {
370 RpcMutexLockGuard _l(blockMutex);
371 return Status::ok();
372 }
373
374 Status sleepMs(int32_t ms) override {
375 usleep(ms * 1000);
376 return Status::ok();
377 }
378
379 Status sleepMsAsync(int32_t ms) override {
380 // In-process binder calls are asynchronous, but the call to this method
381 // is synchronous wrt its client. This in/out-process threading model
382 // diffentiation is a classic binder leaky abstraction (for better or
383 // worse) and is preserved here the way binder sockets plugs itself
384 // into BpBinder, as nothing is changed at the higher levels
385 // (IInterface) which result in this behavior.
386 return sleepMs(ms);
387 }
388
389 Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
390 const std::string& value) override {
391 if (callback == nullptr) {
392 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
393 }
394
395 if (delayed) {
396 RpcMaybeThread([=]() {
397 ALOGE("Executing delayed callback: '%s'", value.c_str());
398 Status status = doCallback(callback, oneway, false, value);
399 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
400 }).detach();
401 return Status::ok();
402 }
403
404 if (oneway) {
405 return callback->sendOnewayCallback(value);
406 }
407
408 return callback->sendCallback(value);
409 }
410
411 Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
412 const std::string& value) override {
413 return doCallback(callback, oneway, delayed, value);
414 }
415
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000416protected:
417 // Generic version of countBinders that works with both
418 // RpcServer and RpcServerTrusty
419 template <typename T>
420 Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
421 sp<T> spServer = server.promote();
422 if (spServer == nullptr) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000423 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
424 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000425 out->clear();
426 for (auto session : spServer->listSessions()) {
427 size_t count = session->state()->countBinders();
428 out->push_back(count);
Andrei Homescu2a298012022-06-15 01:08:54 +0000429 }
430 return Status::ok();
431 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000432};
Andrei Homescu2a298012022-06-15 01:08:54 +0000433
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000434// Default implementation of MyBinderRpcTest that can be used as-is
435// or derived from by classes that only want to implement a subset of
436// the unimplemented methods
437class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
438public:
439 Status countBinders(std::vector<int32_t>* /*out*/) override {
440 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000441 }
442
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000443 Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
444
445 Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
446
447 Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
448
449 Status echoAsFile(const std::string& /*content*/,
450 android::os::ParcelFileDescriptor* /*out*/) override {
451 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000452 }
Frederick Mayleb0221d12022-10-03 23:10:53 +0000453
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000454 Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
455 android::os::ParcelFileDescriptor* /*out*/) override {
456 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000457 }
458
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000459 Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
460 return Status::fromStatusT(UNKNOWN_TRANSACTION);
461 }
462
463 Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
464 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000465 }
Frederick Mayle96872592023-03-07 14:56:15 -0800466
467 Status blockingSendIntOneway(int /*n*/) override {
468 return Status::fromStatusT(UNKNOWN_TRANSACTION);
469 }
470
471 Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
Andrei Homescu2a298012022-06-15 01:08:54 +0000472};
473
474} // namespace android