blob: dfce4417a0eb7d4a5fa402df1830d4e74d02ed93 [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() {
Andrei Homescu331c67e2024-03-27 23:07:01 +000077#ifdef BINDER_RPC_TO_TRUSTY_TEST
78 // Trusty services do not support the experimental version,
79 // so that we can update the prebuilts separately.
80 // This covers the binderRpcToTrustyTest case on Android.
81 return false;
82#endif
Steven Moreland0884c552023-10-17 18:23:31 +000083#ifdef __ANDROID__
84 return base::GetProperty("ro.build.version.codename", "") != "REL";
85#else
Steven Moreland687728e2023-10-28 01:07:40 +000086 return false;
Steven Moreland0884c552023-10-17 18:23:31 +000087#endif
88}
89
Andrei Homescu9d8adb12022-08-02 04:38:30 +000090static inline std::vector<uint32_t> testVersions() {
91 std::vector<uint32_t> versions;
92 for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
93 versions.push_back(i);
94 }
Steven Moreland0884c552023-10-17 18:23:31 +000095 if (hasExperimentalRpc()) {
96 versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
97 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +000098 return versions;
99}
100
101static inline std::string trustyIpcPort(uint32_t serverVersion) {
Tomasz Wasilczyk3caae302023-10-12 20:57:02 +0000102 return std::format("com.android.trusty.binderRpcTestService.V{}", serverVersion);
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000103}
104
Andrei Homescu2a298012022-06-15 01:08:54 +0000105enum class SocketType {
106 PRECONNECTED,
107 UNIX,
David Brazdil21c887c2022-09-23 12:25:18 +0100108 UNIX_BOOTSTRAP,
Alice Wang893a9912022-10-24 10:44:09 +0000109 UNIX_RAW,
Andrei Homescu2a298012022-06-15 01:08:54 +0000110 VSOCK,
111 INET,
Andrei Homescu68a55612022-08-02 01:25:15 +0000112 TIPC,
Andrei Homescu2a298012022-06-15 01:08:54 +0000113};
David Brazdil21c887c2022-09-23 12:25:18 +0100114
Andrei Homescu2a298012022-06-15 01:08:54 +0000115static inline std::string PrintToString(SocketType socketType) {
116 switch (socketType) {
117 case SocketType::PRECONNECTED:
118 return "preconnected_uds";
119 case SocketType::UNIX:
120 return "unix_domain_socket";
David Brazdil21c887c2022-09-23 12:25:18 +0100121 case SocketType::UNIX_BOOTSTRAP:
122 return "unix_domain_socket_bootstrap";
Alice Wang893a9912022-10-24 10:44:09 +0000123 case SocketType::UNIX_RAW:
124 return "raw_uds";
Andrei Homescu2a298012022-06-15 01:08:54 +0000125 case SocketType::VSOCK:
126 return "vm_socket";
127 case SocketType::INET:
128 return "inet_socket";
Andrei Homescu68a55612022-08-02 01:25:15 +0000129 case SocketType::TIPC:
130 return "trusty_ipc";
Andrei Homescu2a298012022-06-15 01:08:54 +0000131 default:
132 LOG_ALWAYS_FATAL("Unknown socket type");
133 return "";
134 }
135}
136
Andrei Homescu9a9b1b42022-10-14 01:40:59 +0000137static inline size_t epochMillis() {
138 using std::chrono::duration_cast;
139 using std::chrono::milliseconds;
140 using std::chrono::seconds;
141 using std::chrono::system_clock;
142 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
143}
144
Andrei Homescu2a298012022-06-15 01:08:54 +0000145struct BinderRpcOptions {
146 size_t numThreads = 1;
147 size_t numSessions = 1;
Steven Moreland67f85902023-03-15 01:13:49 +0000148 // right now, this can be empty, or length numSessions, where each value
149 // represents the info for the corresponding session, but we should
150 // probably switch this to be a list of sessions options so that other
151 // options can all be specified per session
152 std::vector<size_t> numIncomingConnectionsBySession = {};
Andrei Homescu2a298012022-06-15 01:08:54 +0000153 size_t numOutgoingConnections = SIZE_MAX;
154 RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
155 RpcSession::FileDescriptorTransportMode::NONE;
156 std::vector<RpcSession::FileDescriptorTransportMode>
157 serverSupportedFileDescriptorTransportModes = {
158 RpcSession::FileDescriptorTransportMode::NONE};
159
160 // If true, connection failures will result in `ProcessSession::sessions` being empty
161 // instead of a fatal error.
162 bool allowConnectFailure = false;
163};
164
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000165#ifndef __TRUSTY__
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700166static inline void writeString(binder::borrowed_fd fd, std::string_view str) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000167 uint64_t length = str.length();
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700168 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, &length, sizeof(length)));
169 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, str.data(), str.length()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000170}
171
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700172static inline std::string readString(binder::borrowed_fd fd) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000173 uint64_t length;
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700174 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, &length, sizeof(length)));
Andrei Homescu2a298012022-06-15 01:08:54 +0000175 std::string ret(length, '\0');
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700176 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, ret.data(), length));
Andrei Homescu2a298012022-06-15 01:08:54 +0000177 return ret;
178}
179
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700180static inline void writeToFd(binder::borrowed_fd fd, const Parcelable& parcelable) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000181 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700182 LOG_ALWAYS_FATAL_IF(OK != parcelable.writeToParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000183 writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
184}
185
186template <typename T>
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700187static inline T readFromFd(binder::borrowed_fd fd) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000188 std::string data = readString(fd);
189 Parcel parcel;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700190 LOG_ALWAYS_FATAL_IF(OK !=
191 parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
Andrei Homescu2a298012022-06-15 01:08:54 +0000192 T object;
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700193 LOG_ALWAYS_FATAL_IF(OK != object.readFromParcel(&parcel));
Andrei Homescu2a298012022-06-15 01:08:54 +0000194 return object;
195}
196
Andrei Homescuf30148c2023-03-10 00:31:45 +0000197static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
Andrei Homescu2a298012022-06-15 01:08:54 +0000198 RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
199 std::unique_ptr<RpcAuth> auth = nullptr) {
200 switch (rpcSecurity) {
201 case RpcSecurity::RAW:
202 return RpcTransportCtxFactoryRaw::make();
203 case RpcSecurity::TLS: {
204 if (verifier == nullptr) {
205 verifier = std::make_shared<RpcCertificateVerifierSimple>();
206 }
207 if (auth == nullptr) {
208 auth = std::make_unique<RpcAuthSelfSigned>();
209 }
210 return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
211 }
212 default:
Tomasz Wasilczyke97f3a82024-04-30 10:37:32 -0700213 LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", static_cast<int>(rpcSecurity));
Andrei Homescu2a298012022-06-15 01:08:54 +0000214 }
215}
216
217// Create an FD that returns `contents` when read.
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -0700218static inline binder::unique_fd mockFileDescriptor(std::string contents) {
219 binder::unique_fd readFd, writeFd;
220 LOG_ALWAYS_FATAL_IF(!binder::Pipe(&readFd, &writeFd), "%s", strerror(errno));
Andrei Homescu2a298012022-06-15 01:08:54 +0000221 RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
222 signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
Tomasz Wasilczyk26db5e42023-11-02 11:45:11 -0700223 if (!android::binder::WriteStringToFd(contents, writeFd)) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000224 int savedErrno = errno;
225 LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
226 strerror(savedErrno));
227 }
228 }).detach();
229 return readFd;
230}
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000231#endif // __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000232
Frederick Mayleb0221d12022-10-03 23:10:53 +0000233// A threadsafe channel where writes block until the value is read.
234template <typename T>
235class HandoffChannel {
236public:
237 void write(T v) {
238 {
239 RpcMutexUniqueLock lock(mMutex);
240 // Wait for space to send.
241 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
242 mValue.emplace(std::move(v));
243 }
244 mCvFull.notify_all();
245 RpcMutexUniqueLock lock(mMutex);
246 // Wait for it to be taken.
247 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
248 }
249
250 T read() {
251 RpcMutexUniqueLock lock(mMutex);
252 if (!mValue.has_value()) {
253 mCvFull.wait(lock, [&]() { return mValue.has_value(); });
254 }
255 T v = std::move(mValue.value());
256 mValue.reset();
257 lock.unlock();
258 mCvEmpty.notify_all();
Tomasz Wasilczyke97f3a82024-04-30 10:37:32 -0700259 return v;
Frederick Mayleb0221d12022-10-03 23:10:53 +0000260 }
261
262private:
263 RpcMutex mMutex;
264 RpcConditionVariable mCvEmpty;
265 RpcConditionVariable mCvFull;
266 std::optional<T> mValue;
267};
268
Andrei Homescu2a298012022-06-15 01:08:54 +0000269using android::binder::Status;
270
271class MyBinderRpcSession : public BnBinderRpcSession {
272public:
273 static std::atomic<int32_t> gNum;
274
275 MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
276 Status getName(std::string* name) override {
277 *name = mName;
278 return Status::ok();
279 }
280 ~MyBinderRpcSession() { gNum--; }
281
282private:
283 std::string mName;
284};
285
286class MyBinderRpcCallback : public BnBinderRpcCallback {
287 Status sendCallback(const std::string& value) {
288 RpcMutexUniqueLock _l(mMutex);
289 mValues.push_back(value);
290 _l.unlock();
291 mCv.notify_one();
292 return Status::ok();
293 }
294 Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
295
296public:
297 RpcMutex mMutex;
298 RpcConditionVariable mCv;
299 std::vector<std::string> mValues;
300};
301
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000302// Base class for all concrete implementations of MyBinderRpcTest.
303// Sub-classes that want to provide a full implementation should derive
304// from this class instead of MyBinderRpcTestDefault below so the compiler
305// checks that all methods are implemented.
306class MyBinderRpcTestBase : public BnBinderRpcTest {
Andrei Homescu2a298012022-06-15 01:08:54 +0000307public:
Andrei Homescu2a298012022-06-15 01:08:54 +0000308 int port = 0;
309
310 Status sendString(const std::string& str) override {
311 (void)str;
312 return Status::ok();
313 }
314 Status doubleString(const std::string& str, std::string* strstr) override {
315 *strstr = str + str;
316 return Status::ok();
317 }
318 Status getClientPort(int* out) override {
319 *out = port;
320 return Status::ok();
321 }
Andrei Homescu2a298012022-06-15 01:08:54 +0000322 Status getNullBinder(sp<IBinder>* out) override {
323 out->clear();
324 return Status::ok();
325 }
326 Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
327 if (binder == nullptr) {
328 std::cout << "Received null binder!" << std::endl;
329 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
330 }
331 *out = binder->pingBinder();
332 return Status::ok();
333 }
334 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
335 *out = binder;
336 return Status::ok();
337 }
338 static sp<IBinder> mHeldBinder;
339 Status holdBinder(const sp<IBinder>& binder) override {
340 mHeldBinder = binder;
341 return Status::ok();
342 }
343 Status getHeldBinder(sp<IBinder>* held) override {
344 *held = mHeldBinder;
345 return Status::ok();
346 }
347 Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
348 if (count <= 0) return Status::ok();
349 return binder->nestMe(this, count - 1);
350 }
351 Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
352 static sp<IBinder> binder = new BBinder;
353 *out = binder;
354 return Status::ok();
355 }
356 Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
357 *out = new MyBinderRpcSession(name);
358 return Status::ok();
359 }
360 Status getNumOpenSessions(int32_t* out) override {
361 *out = MyBinderRpcSession::gNum;
362 return Status::ok();
363 }
364
365 RpcMutex blockMutex;
366 Status lock() override {
367 blockMutex.lock();
368 return Status::ok();
369 }
370 Status unlockInMsAsync(int32_t ms) override {
371 usleep(ms * 1000);
372 blockMutex.unlock();
373 return Status::ok();
374 }
375 Status lockUnlock() override {
376 RpcMutexLockGuard _l(blockMutex);
377 return Status::ok();
378 }
379
380 Status sleepMs(int32_t ms) override {
381 usleep(ms * 1000);
382 return Status::ok();
383 }
384
385 Status sleepMsAsync(int32_t ms) override {
386 // In-process binder calls are asynchronous, but the call to this method
387 // is synchronous wrt its client. This in/out-process threading model
388 // diffentiation is a classic binder leaky abstraction (for better or
389 // worse) and is preserved here the way binder sockets plugs itself
390 // into BpBinder, as nothing is changed at the higher levels
391 // (IInterface) which result in this behavior.
392 return sleepMs(ms);
393 }
394
395 Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
396 const std::string& value) override {
397 if (callback == nullptr) {
398 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
399 }
400
401 if (delayed) {
Tomasz Wasilczyke9c93a72023-12-04 11:53:26 -0800402 RpcMaybeThread([=, this]() {
Andrei Homescu2a298012022-06-15 01:08:54 +0000403 ALOGE("Executing delayed callback: '%s'", value.c_str());
404 Status status = doCallback(callback, oneway, false, value);
405 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
406 }).detach();
407 return Status::ok();
408 }
409
410 if (oneway) {
411 return callback->sendOnewayCallback(value);
412 }
413
414 return callback->sendCallback(value);
415 }
416
417 Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
418 const std::string& value) override {
419 return doCallback(callback, oneway, delayed, value);
420 }
421
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000422protected:
423 // Generic version of countBinders that works with both
424 // RpcServer and RpcServerTrusty
425 template <typename T>
426 Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
427 sp<T> spServer = server.promote();
428 if (spServer == nullptr) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000429 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
430 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000431 out->clear();
432 for (auto session : spServer->listSessions()) {
433 size_t count = session->state()->countBinders();
434 out->push_back(count);
Andrei Homescu2a298012022-06-15 01:08:54 +0000435 }
436 return Status::ok();
437 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000438};
Andrei Homescu2a298012022-06-15 01:08:54 +0000439
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000440// Default implementation of MyBinderRpcTest that can be used as-is
441// or derived from by classes that only want to implement a subset of
442// the unimplemented methods
443class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
444public:
445 Status countBinders(std::vector<int32_t>* /*out*/) override {
446 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000447 }
448
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000449 Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
450
451 Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
452
453 Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
454
455 Status echoAsFile(const std::string& /*content*/,
456 android::os::ParcelFileDescriptor* /*out*/) override {
457 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000458 }
Frederick Mayleb0221d12022-10-03 23:10:53 +0000459
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000460 Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
461 android::os::ParcelFileDescriptor* /*out*/) override {
462 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000463 }
464
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000465 Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
466 return Status::fromStatusT(UNKNOWN_TRANSACTION);
467 }
468
469 Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
470 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000471 }
Frederick Mayle96872592023-03-07 14:56:15 -0800472
473 Status blockingSendIntOneway(int /*n*/) override {
474 return Status::fromStatusT(UNKNOWN_TRANSACTION);
475 }
476
477 Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
Andrei Homescu2a298012022-06-15 01:08:54 +0000478};
479
480} // namespace android