blob: acc0373bf45736c713d39935ed6af5c0ceb8a23f [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"
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() {
Andrei Homescu331c67e2024-03-27 23:07:01 +000076#ifdef BINDER_RPC_TO_TRUSTY_TEST
77 // Trusty services do not support the experimental version,
78 // so that we can update the prebuilts separately.
79 // This covers the binderRpcToTrustyTest case on Android.
80 return false;
81#endif
Steven Moreland0884c552023-10-17 18:23:31 +000082#ifdef __ANDROID__
83 return base::GetProperty("ro.build.version.codename", "") != "REL";
84#else
Steven Moreland687728e2023-10-28 01:07:40 +000085 return false;
Steven Moreland0884c552023-10-17 18:23:31 +000086#endif
87}
88
Andrei Homescu9d8adb12022-08-02 04:38:30 +000089static inline std::vector<uint32_t> testVersions() {
90 std::vector<uint32_t> versions;
91 for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
92 versions.push_back(i);
93 }
Steven Moreland0884c552023-10-17 18:23:31 +000094 if (hasExperimentalRpc()) {
95 versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
96 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +000097 return versions;
98}
99
100static inline std::string trustyIpcPort(uint32_t serverVersion) {
Tomasz Wasilczyk68c42082024-05-20 11:59:35 -0700101 return "com.android.trusty.binderRpcTestService.V" + std::to_string(serverVersion);
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000102}
103
Andrei Homescu2a298012022-06-15 01:08:54 +0000104enum class SocketType {
105 PRECONNECTED,
106 UNIX,
David Brazdil21c887c2022-09-23 12:25:18 +0100107 UNIX_BOOTSTRAP,
Alice Wang893a9912022-10-24 10:44:09 +0000108 UNIX_RAW,
Andrei Homescu2a298012022-06-15 01:08:54 +0000109 VSOCK,
110 INET,
Andrei Homescu68a55612022-08-02 01:25:15 +0000111 TIPC,
Andrei Homescu2a298012022-06-15 01:08:54 +0000112};
David Brazdil21c887c2022-09-23 12:25:18 +0100113
Andrei Homescu2a298012022-06-15 01:08:54 +0000114static inline std::string PrintToString(SocketType socketType) {
115 switch (socketType) {
116 case SocketType::PRECONNECTED:
117 return "preconnected_uds";
118 case SocketType::UNIX:
119 return "unix_domain_socket";
David Brazdil21c887c2022-09-23 12:25:18 +0100120 case SocketType::UNIX_BOOTSTRAP:
121 return "unix_domain_socket_bootstrap";
Alice Wang893a9912022-10-24 10:44:09 +0000122 case SocketType::UNIX_RAW:
123 return "raw_uds";
Andrei Homescu2a298012022-06-15 01:08:54 +0000124 case SocketType::VSOCK:
125 return "vm_socket";
126 case SocketType::INET:
127 return "inet_socket";
Andrei Homescu68a55612022-08-02 01:25:15 +0000128 case SocketType::TIPC:
129 return "trusty_ipc";
Andrei Homescu2a298012022-06-15 01:08:54 +0000130 default:
131 LOG_ALWAYS_FATAL("Unknown socket type");
132 return "";
133 }
134}
135
Andrei Homescu9a9b1b42022-10-14 01:40:59 +0000136static inline size_t epochMillis() {
137 using std::chrono::duration_cast;
138 using std::chrono::milliseconds;
139 using std::chrono::seconds;
140 using std::chrono::system_clock;
141 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
142}
143
Andrei Homescu2a298012022-06-15 01:08:54 +0000144struct BinderRpcOptions {
145 size_t numThreads = 1;
146 size_t numSessions = 1;
Steven Moreland67f85902023-03-15 01:13:49 +0000147 // right now, this can be empty, or length numSessions, where each value
148 // represents the info for the corresponding session, but we should
149 // probably switch this to be a list of sessions options so that other
150 // options can all be specified per session
151 std::vector<size_t> numIncomingConnectionsBySession = {};
Andrei Homescu2a298012022-06-15 01:08:54 +0000152 size_t numOutgoingConnections = SIZE_MAX;
153 RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
154 RpcSession::FileDescriptorTransportMode::NONE;
155 std::vector<RpcSession::FileDescriptorTransportMode>
156 serverSupportedFileDescriptorTransportModes = {
157 RpcSession::FileDescriptorTransportMode::NONE};
158
159 // If true, connection failures will result in `ProcessSession::sessions` being empty
160 // instead of a fatal error.
161 bool allowConnectFailure = false;
162};
163
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000164#ifndef __TRUSTY__
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700165static inline void writeString(binder::borrowed_fd fd, std::string_view str) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000166 uint64_t length = str.length();
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700167 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, &length, sizeof(length)));
168 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, str.data(), str.length()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000169}
170
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700171static inline std::string readString(binder::borrowed_fd fd) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000172 uint64_t length;
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700173 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, &length, sizeof(length)));
Andrei Homescu2a298012022-06-15 01:08:54 +0000174 std::string ret(length, '\0');
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700175 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, ret.data(), length));
Andrei Homescu2a298012022-06-15 01:08:54 +0000176 return ret;
177}
178
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700179static inline void writeToFd(binder::borrowed_fd fd, const Parcelable& parcelable) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000180 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700181 LOG_ALWAYS_FATAL_IF(OK != parcelable.writeToParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000182 writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
183}
184
185template <typename T>
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700186static inline T readFromFd(binder::borrowed_fd fd) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000187 std::string data = readString(fd);
188 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700189 LOG_ALWAYS_FATAL_IF(OK !=
190 parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000191 T object;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700192 LOG_ALWAYS_FATAL_IF(OK != object.readFromParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000193 return object;
194}
195
Andrei Homescuf30148c2023-03-10 00:31:45 +0000196static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
Andrei Homescu2a298012022-06-15 01:08:54 +0000197 RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
198 std::unique_ptr<RpcAuth> auth = nullptr) {
199 switch (rpcSecurity) {
200 case RpcSecurity::RAW:
201 return RpcTransportCtxFactoryRaw::make();
202 case RpcSecurity::TLS: {
203 if (verifier == nullptr) {
204 verifier = std::make_shared<RpcCertificateVerifierSimple>();
205 }
206 if (auth == nullptr) {
207 auth = std::make_unique<RpcAuthSelfSigned>();
208 }
209 return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
210 }
211 default:
Tomasz Wasilczyke97f3a82024-04-30 10:37:32 -0700212 LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", static_cast<int>(rpcSecurity));
Andrei Homescu2a298012022-06-15 01:08:54 +0000213 }
214}
215
216// Create an FD that returns `contents` when read.
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700217static inline binder::unique_fd mockFileDescriptor(std::string contents) {
218 binder::unique_fd readFd, writeFd;
219 LOG_ALWAYS_FATAL_IF(!binder::Pipe(&readFd, &writeFd), "%s", strerror(errno));
Andrei Homescu2a298012022-06-15 01:08:54 +0000220 RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
221 signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700222 if (!android::binder::WriteStringToFd(contents, writeFd)) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000223 int savedErrno = errno;
224 LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
225 strerror(savedErrno));
226 }
227 }).detach();
228 return readFd;
229}
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000230#endif // __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000231
Frederick Mayleb0221d12022-10-03 23:10:53 +0000232// A threadsafe channel where writes block until the value is read.
233template <typename T>
234class HandoffChannel {
235public:
236 void write(T v) {
237 {
238 RpcMutexUniqueLock lock(mMutex);
239 // Wait for space to send.
240 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
241 mValue.emplace(std::move(v));
242 }
243 mCvFull.notify_all();
244 RpcMutexUniqueLock lock(mMutex);
245 // Wait for it to be taken.
246 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
247 }
248
249 T read() {
250 RpcMutexUniqueLock lock(mMutex);
251 if (!mValue.has_value()) {
252 mCvFull.wait(lock, [&]() { return mValue.has_value(); });
253 }
254 T v = std::move(mValue.value());
255 mValue.reset();
256 lock.unlock();
257 mCvEmpty.notify_all();
Tomasz Wasilczyke97f3a82024-04-30 10:37:32 -0700258 return v;
Frederick Mayleb0221d12022-10-03 23:10:53 +0000259 }
260
261private:
262 RpcMutex mMutex;
263 RpcConditionVariable mCvEmpty;
264 RpcConditionVariable mCvFull;
265 std::optional<T> mValue;
266};
267
Andrei Homescu2a298012022-06-15 01:08:54 +0000268using android::binder::Status;
269
270class MyBinderRpcSession : public BnBinderRpcSession {
271public:
272 static std::atomic<int32_t> gNum;
273
274 MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
275 Status getName(std::string* name) override {
276 *name = mName;
277 return Status::ok();
278 }
279 ~MyBinderRpcSession() { gNum--; }
280
281private:
282 std::string mName;
283};
284
285class MyBinderRpcCallback : public BnBinderRpcCallback {
286 Status sendCallback(const std::string& value) {
287 RpcMutexUniqueLock _l(mMutex);
288 mValues.push_back(value);
289 _l.unlock();
290 mCv.notify_one();
291 return Status::ok();
292 }
293 Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
294
295public:
296 RpcMutex mMutex;
297 RpcConditionVariable mCv;
298 std::vector<std::string> mValues;
299};
300
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000301// Base class for all concrete implementations of MyBinderRpcTest.
302// Sub-classes that want to provide a full implementation should derive
303// from this class instead of MyBinderRpcTestDefault below so the compiler
304// checks that all methods are implemented.
305class MyBinderRpcTestBase : public BnBinderRpcTest {
Andrei Homescu2a298012022-06-15 01:08:54 +0000306public:
Andrei Homescu2a298012022-06-15 01:08:54 +0000307 int port = 0;
308
309 Status sendString(const std::string& str) override {
310 (void)str;
311 return Status::ok();
312 }
313 Status doubleString(const std::string& str, std::string* strstr) override {
314 *strstr = str + str;
315 return Status::ok();
316 }
317 Status getClientPort(int* out) override {
318 *out = port;
319 return Status::ok();
320 }
Andrei Homescu2a298012022-06-15 01:08:54 +0000321 Status getNullBinder(sp<IBinder>* out) override {
322 out->clear();
323 return Status::ok();
324 }
325 Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
326 if (binder == nullptr) {
327 std::cout << "Received null binder!" << std::endl;
328 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
329 }
330 *out = binder->pingBinder();
331 return Status::ok();
332 }
333 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
334 *out = binder;
335 return Status::ok();
336 }
337 static sp<IBinder> mHeldBinder;
338 Status holdBinder(const sp<IBinder>& binder) override {
339 mHeldBinder = binder;
340 return Status::ok();
341 }
342 Status getHeldBinder(sp<IBinder>* held) override {
343 *held = mHeldBinder;
344 return Status::ok();
345 }
346 Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
347 if (count <= 0) return Status::ok();
348 return binder->nestMe(this, count - 1);
349 }
350 Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
351 static sp<IBinder> binder = new BBinder;
352 *out = binder;
353 return Status::ok();
354 }
355 Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
356 *out = new MyBinderRpcSession(name);
357 return Status::ok();
358 }
359 Status getNumOpenSessions(int32_t* out) override {
360 *out = MyBinderRpcSession::gNum;
361 return Status::ok();
362 }
363
364 RpcMutex blockMutex;
365 Status lock() override {
366 blockMutex.lock();
367 return Status::ok();
368 }
369 Status unlockInMsAsync(int32_t ms) override {
370 usleep(ms * 1000);
371 blockMutex.unlock();
372 return Status::ok();
373 }
374 Status lockUnlock() override {
375 RpcMutexLockGuard _l(blockMutex);
376 return Status::ok();
377 }
378
379 Status sleepMs(int32_t ms) override {
380 usleep(ms * 1000);
381 return Status::ok();
382 }
383
384 Status sleepMsAsync(int32_t ms) override {
385 // In-process binder calls are asynchronous, but the call to this method
386 // is synchronous wrt its client. This in/out-process threading model
387 // diffentiation is a classic binder leaky abstraction (for better or
388 // worse) and is preserved here the way binder sockets plugs itself
389 // into BpBinder, as nothing is changed at the higher levels
390 // (IInterface) which result in this behavior.
391 return sleepMs(ms);
392 }
393
394 Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
395 const std::string& value) override {
396 if (callback == nullptr) {
397 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
398 }
399
400 if (delayed) {
Tomasz Wasilczyke9c93a72023-12-04 11:53:26 -0800401 RpcMaybeThread([=, this]() {
Andrei Homescu2a298012022-06-15 01:08:54 +0000402 ALOGE("Executing delayed callback: '%s'", value.c_str());
403 Status status = doCallback(callback, oneway, false, value);
404 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
405 }).detach();
406 return Status::ok();
407 }
408
409 if (oneway) {
410 return callback->sendOnewayCallback(value);
411 }
412
413 return callback->sendCallback(value);
414 }
415
416 Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
417 const std::string& value) override {
418 return doCallback(callback, oneway, delayed, value);
419 }
420
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000421protected:
422 // Generic version of countBinders that works with both
423 // RpcServer and RpcServerTrusty
424 template <typename T>
425 Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
426 sp<T> spServer = server.promote();
427 if (spServer == nullptr) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000428 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
429 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000430 out->clear();
431 for (auto session : spServer->listSessions()) {
432 size_t count = session->state()->countBinders();
433 out->push_back(count);
Andrei Homescu2a298012022-06-15 01:08:54 +0000434 }
435 return Status::ok();
436 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000437};
Andrei Homescu2a298012022-06-15 01:08:54 +0000438
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000439// Default implementation of MyBinderRpcTest that can be used as-is
440// or derived from by classes that only want to implement a subset of
441// the unimplemented methods
442class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
443public:
444 Status countBinders(std::vector<int32_t>* /*out*/) override {
445 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000446 }
447
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000448 Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
449
450 Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
451
452 Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
453
454 Status echoAsFile(const std::string& /*content*/,
455 android::os::ParcelFileDescriptor* /*out*/) override {
456 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000457 }
Frederick Mayleb0221d12022-10-03 23:10:53 +0000458
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000459 Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
460 android::os::ParcelFileDescriptor* /*out*/) override {
461 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000462 }
463
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000464 Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
465 return Status::fromStatusT(UNKNOWN_TRANSACTION);
466 }
467
468 Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
469 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000470 }
Frederick Mayle96872592023-03-07 14:56:15 -0800471
472 Status blockingSendIntOneway(int /*n*/) override {
473 return Status::fromStatusT(UNKNOWN_TRANSACTION);
474 }
475
476 Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
Andrei Homescu2a298012022-06-15 01:08:54 +0000477};
478
479} // namespace android