blob: a467ee389be5f737b4eedc2563e270e3a2388fd6 [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 <android-base/stringprintf.h>
26#include <binder/Binder.h>
27#include <binder/BpBinder.h>
28#include <binder/IPCThreadState.h>
29#include <binder/IServiceManager.h>
30#include <binder/RpcServer.h>
31#include <binder/RpcSession.h>
32#include <binder/RpcThreads.h>
33#include <binder/RpcTransport.h>
34#include <binder/RpcTransportRaw.h>
35#include <unistd.h>
36#include <cinttypes>
37#include <string>
38#include <vector>
39
40#ifndef __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +000041#include <android-base/file.h>
42#include <android-base/logging.h>
43#include <android-base/properties.h>
44#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"
60#include "../RpcState.h" // for debugging
Andrei Homescu2a298012022-06-15 01:08:54 +000061#include "utils/Errors.h"
62
63namespace android {
64
65constexpr char kLocalInetAddress[] = "127.0.0.1";
66
67enum class RpcSecurity { RAW, TLS };
68
69static inline std::vector<RpcSecurity> RpcSecurityValues() {
70 return {RpcSecurity::RAW, RpcSecurity::TLS};
71}
72
Andrei Homescu9d8adb12022-08-02 04:38:30 +000073static inline std::vector<uint32_t> testVersions() {
74 std::vector<uint32_t> versions;
75 for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
76 versions.push_back(i);
77 }
78 versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
79 return versions;
80}
81
82static inline std::string trustyIpcPort(uint32_t serverVersion) {
83 return base::StringPrintf("com.android.trusty.binderRpcTestService.V%" PRIu32, serverVersion);
84}
85
Andrei Homescu2a298012022-06-15 01:08:54 +000086enum class SocketType {
87 PRECONNECTED,
88 UNIX,
David Brazdil21c887c2022-09-23 12:25:18 +010089 UNIX_BOOTSTRAP,
Alice Wang893a9912022-10-24 10:44:09 +000090 UNIX_RAW,
Andrei Homescu2a298012022-06-15 01:08:54 +000091 VSOCK,
92 INET,
Andrei Homescu68a55612022-08-02 01:25:15 +000093 TIPC,
Andrei Homescu2a298012022-06-15 01:08:54 +000094};
David Brazdil21c887c2022-09-23 12:25:18 +010095
Andrei Homescu2a298012022-06-15 01:08:54 +000096static inline std::string PrintToString(SocketType socketType) {
97 switch (socketType) {
98 case SocketType::PRECONNECTED:
99 return "preconnected_uds";
100 case SocketType::UNIX:
101 return "unix_domain_socket";
David Brazdil21c887c2022-09-23 12:25:18 +0100102 case SocketType::UNIX_BOOTSTRAP:
103 return "unix_domain_socket_bootstrap";
Alice Wang893a9912022-10-24 10:44:09 +0000104 case SocketType::UNIX_RAW:
105 return "raw_uds";
Andrei Homescu2a298012022-06-15 01:08:54 +0000106 case SocketType::VSOCK:
107 return "vm_socket";
108 case SocketType::INET:
109 return "inet_socket";
Andrei Homescu68a55612022-08-02 01:25:15 +0000110 case SocketType::TIPC:
111 return "trusty_ipc";
Andrei Homescu2a298012022-06-15 01:08:54 +0000112 default:
113 LOG_ALWAYS_FATAL("Unknown socket type");
114 return "";
115 }
116}
117
Andrei Homescu9a9b1b42022-10-14 01:40:59 +0000118static inline size_t epochMillis() {
119 using std::chrono::duration_cast;
120 using std::chrono::milliseconds;
121 using std::chrono::seconds;
122 using std::chrono::system_clock;
123 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
124}
125
Andrei Homescu2a298012022-06-15 01:08:54 +0000126struct BinderRpcOptions {
127 size_t numThreads = 1;
128 size_t numSessions = 1;
129 size_t numIncomingConnections = 0;
130 size_t numOutgoingConnections = SIZE_MAX;
131 RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
132 RpcSession::FileDescriptorTransportMode::NONE;
133 std::vector<RpcSession::FileDescriptorTransportMode>
134 serverSupportedFileDescriptorTransportModes = {
135 RpcSession::FileDescriptorTransportMode::NONE};
136
137 // If true, connection failures will result in `ProcessSession::sessions` being empty
138 // instead of a fatal error.
139 bool allowConnectFailure = false;
140};
141
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000142#ifndef __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000143static inline void writeString(android::base::borrowed_fd fd, std::string_view str) {
144 uint64_t length = str.length();
145 CHECK(android::base::WriteFully(fd, &length, sizeof(length)));
146 CHECK(android::base::WriteFully(fd, str.data(), str.length()));
147}
148
149static inline std::string readString(android::base::borrowed_fd fd) {
150 uint64_t length;
151 CHECK(android::base::ReadFully(fd, &length, sizeof(length)));
152 std::string ret(length, '\0');
153 CHECK(android::base::ReadFully(fd, ret.data(), length));
154 return ret;
155}
156
157static inline void writeToFd(android::base::borrowed_fd fd, const Parcelable& parcelable) {
158 Parcel parcel;
159 CHECK_EQ(OK, parcelable.writeToParcel(&parcel));
160 writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
161}
162
163template <typename T>
164static inline T readFromFd(android::base::borrowed_fd fd) {
165 std::string data = readString(fd);
166 Parcel parcel;
167 CHECK_EQ(OK, parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
168 T object;
169 CHECK_EQ(OK, object.readFromParcel(&parcel));
170 return object;
171}
172
173static inline std::unique_ptr<RpcTransportCtxFactory> newFactory(
174 RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
175 std::unique_ptr<RpcAuth> auth = nullptr) {
176 switch (rpcSecurity) {
177 case RpcSecurity::RAW:
178 return RpcTransportCtxFactoryRaw::make();
179 case RpcSecurity::TLS: {
180 if (verifier == nullptr) {
181 verifier = std::make_shared<RpcCertificateVerifierSimple>();
182 }
183 if (auth == nullptr) {
184 auth = std::make_unique<RpcAuthSelfSigned>();
185 }
186 return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
187 }
188 default:
189 LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
190 }
191}
192
193// Create an FD that returns `contents` when read.
194static inline base::unique_fd mockFileDescriptor(std::string contents) {
195 android::base::unique_fd readFd, writeFd;
196 CHECK(android::base::Pipe(&readFd, &writeFd)) << strerror(errno);
197 RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
198 signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
199 if (!WriteStringToFd(contents, writeFd)) {
200 int savedErrno = errno;
201 LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
202 strerror(savedErrno));
203 }
204 }).detach();
205 return readFd;
206}
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000207#endif // __TRUSTY__
Andrei Homescu2a298012022-06-15 01:08:54 +0000208
Frederick Mayleb0221d12022-10-03 23:10:53 +0000209// A threadsafe channel where writes block until the value is read.
210template <typename T>
211class HandoffChannel {
212public:
213 void write(T v) {
214 {
215 RpcMutexUniqueLock lock(mMutex);
216 // Wait for space to send.
217 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
218 mValue.emplace(std::move(v));
219 }
220 mCvFull.notify_all();
221 RpcMutexUniqueLock lock(mMutex);
222 // Wait for it to be taken.
223 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
224 }
225
226 T read() {
227 RpcMutexUniqueLock lock(mMutex);
228 if (!mValue.has_value()) {
229 mCvFull.wait(lock, [&]() { return mValue.has_value(); });
230 }
231 T v = std::move(mValue.value());
232 mValue.reset();
233 lock.unlock();
234 mCvEmpty.notify_all();
235 return std::move(v);
236 }
237
238private:
239 RpcMutex mMutex;
240 RpcConditionVariable mCvEmpty;
241 RpcConditionVariable mCvFull;
242 std::optional<T> mValue;
243};
244
Andrei Homescu2a298012022-06-15 01:08:54 +0000245using android::binder::Status;
246
247class MyBinderRpcSession : public BnBinderRpcSession {
248public:
249 static std::atomic<int32_t> gNum;
250
251 MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
252 Status getName(std::string* name) override {
253 *name = mName;
254 return Status::ok();
255 }
256 ~MyBinderRpcSession() { gNum--; }
257
258private:
259 std::string mName;
260};
261
262class MyBinderRpcCallback : public BnBinderRpcCallback {
263 Status sendCallback(const std::string& value) {
264 RpcMutexUniqueLock _l(mMutex);
265 mValues.push_back(value);
266 _l.unlock();
267 mCv.notify_one();
268 return Status::ok();
269 }
270 Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
271
272public:
273 RpcMutex mMutex;
274 RpcConditionVariable mCv;
275 std::vector<std::string> mValues;
276};
277
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000278// Base class for all concrete implementations of MyBinderRpcTest.
279// Sub-classes that want to provide a full implementation should derive
280// from this class instead of MyBinderRpcTestDefault below so the compiler
281// checks that all methods are implemented.
282class MyBinderRpcTestBase : public BnBinderRpcTest {
Andrei Homescu2a298012022-06-15 01:08:54 +0000283public:
Andrei Homescu2a298012022-06-15 01:08:54 +0000284 int port = 0;
285
286 Status sendString(const std::string& str) override {
287 (void)str;
288 return Status::ok();
289 }
290 Status doubleString(const std::string& str, std::string* strstr) override {
291 *strstr = str + str;
292 return Status::ok();
293 }
294 Status getClientPort(int* out) override {
295 *out = port;
296 return Status::ok();
297 }
Andrei Homescu2a298012022-06-15 01:08:54 +0000298 Status getNullBinder(sp<IBinder>* out) override {
299 out->clear();
300 return Status::ok();
301 }
302 Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
303 if (binder == nullptr) {
304 std::cout << "Received null binder!" << std::endl;
305 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
306 }
307 *out = binder->pingBinder();
308 return Status::ok();
309 }
310 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
311 *out = binder;
312 return Status::ok();
313 }
314 static sp<IBinder> mHeldBinder;
315 Status holdBinder(const sp<IBinder>& binder) override {
316 mHeldBinder = binder;
317 return Status::ok();
318 }
319 Status getHeldBinder(sp<IBinder>* held) override {
320 *held = mHeldBinder;
321 return Status::ok();
322 }
323 Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
324 if (count <= 0) return Status::ok();
325 return binder->nestMe(this, count - 1);
326 }
327 Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
328 static sp<IBinder> binder = new BBinder;
329 *out = binder;
330 return Status::ok();
331 }
332 Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
333 *out = new MyBinderRpcSession(name);
334 return Status::ok();
335 }
336 Status getNumOpenSessions(int32_t* out) override {
337 *out = MyBinderRpcSession::gNum;
338 return Status::ok();
339 }
340
341 RpcMutex blockMutex;
342 Status lock() override {
343 blockMutex.lock();
344 return Status::ok();
345 }
346 Status unlockInMsAsync(int32_t ms) override {
347 usleep(ms * 1000);
348 blockMutex.unlock();
349 return Status::ok();
350 }
351 Status lockUnlock() override {
352 RpcMutexLockGuard _l(blockMutex);
353 return Status::ok();
354 }
355
356 Status sleepMs(int32_t ms) override {
357 usleep(ms * 1000);
358 return Status::ok();
359 }
360
361 Status sleepMsAsync(int32_t ms) override {
362 // In-process binder calls are asynchronous, but the call to this method
363 // is synchronous wrt its client. This in/out-process threading model
364 // diffentiation is a classic binder leaky abstraction (for better or
365 // worse) and is preserved here the way binder sockets plugs itself
366 // into BpBinder, as nothing is changed at the higher levels
367 // (IInterface) which result in this behavior.
368 return sleepMs(ms);
369 }
370
371 Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
372 const std::string& value) override {
373 if (callback == nullptr) {
374 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
375 }
376
377 if (delayed) {
378 RpcMaybeThread([=]() {
379 ALOGE("Executing delayed callback: '%s'", value.c_str());
380 Status status = doCallback(callback, oneway, false, value);
381 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
382 }).detach();
383 return Status::ok();
384 }
385
386 if (oneway) {
387 return callback->sendOnewayCallback(value);
388 }
389
390 return callback->sendCallback(value);
391 }
392
393 Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
394 const std::string& value) override {
395 return doCallback(callback, oneway, delayed, value);
396 }
397
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000398protected:
399 // Generic version of countBinders that works with both
400 // RpcServer and RpcServerTrusty
401 template <typename T>
402 Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
403 sp<T> spServer = server.promote();
404 if (spServer == nullptr) {
Andrei Homescu2a298012022-06-15 01:08:54 +0000405 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
406 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000407 out->clear();
408 for (auto session : spServer->listSessions()) {
409 size_t count = session->state()->countBinders();
410 out->push_back(count);
Andrei Homescu2a298012022-06-15 01:08:54 +0000411 }
412 return Status::ok();
413 }
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000414};
Andrei Homescu2a298012022-06-15 01:08:54 +0000415
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000416// Default implementation of MyBinderRpcTest that can be used as-is
417// or derived from by classes that only want to implement a subset of
418// the unimplemented methods
419class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
420public:
421 Status countBinders(std::vector<int32_t>* /*out*/) override {
422 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000423 }
424
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000425 Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
426
427 Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
428
429 Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
430
431 Status echoAsFile(const std::string& /*content*/,
432 android::os::ParcelFileDescriptor* /*out*/) override {
433 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Andrei Homescu2a298012022-06-15 01:08:54 +0000434 }
Frederick Mayleb0221d12022-10-03 23:10:53 +0000435
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000436 Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
437 android::os::ParcelFileDescriptor* /*out*/) override {
438 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000439 }
440
Andrei Homescu9d8adb12022-08-02 04:38:30 +0000441 Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
442 return Status::fromStatusT(UNKNOWN_TRANSACTION);
443 }
444
445 Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
446 return Status::fromStatusT(UNKNOWN_TRANSACTION);
Frederick Mayleb0221d12022-10-03 23:10:53 +0000447 }
Andrei Homescu2a298012022-06-15 01:08:54 +0000448};
449
450} // namespace android