1 /*
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>
25 #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 #ifdef __ANDROID__
40 #include <android-base/properties.h>
41 #endif
42
43 #ifndef __TRUSTY__
44 #include <android/binder_auto_utils.h>
45 #include <android/binder_libbinder.h>
46 #include <binder/ProcessState.h>
47 #include <binder/RpcTlsTestUtils.h>
48 #include <binder/RpcTlsUtils.h>
49 #include <binder/RpcTransportTls.h>
50
51 #include <signal.h>
52
53 #include "../OS.h" // for testing UnixBootstrap clients
54 #include "../RpcSocketAddress.h" // for testing preconnected clients
55 #include "../vm_sockets.h" // for VMADDR_*
56 #endif // __TRUSTY__
57
58 #include "../BuildFlags.h"
59 #include "../FdTrigger.h"
60 #include "../FdUtils.h"
61 #include "../RpcState.h" // for debugging
62 #include "FileUtils.h"
63 #include "utils/Errors.h"
64
65 namespace android {
66
67 #ifdef BINDER_NO_KERNEL_IPC_TESTING
68 constexpr bool kEnableKernelIpcTesting = false;
69 #else
70 constexpr bool kEnableKernelIpcTesting = true;
71 #endif
72
73 constexpr char kLocalInetAddress[] = "127.0.0.1";
74
75 enum class RpcSecurity { RAW, TLS };
76
RpcSecurityValues()77 static inline std::vector<RpcSecurity> RpcSecurityValues() {
78 return {RpcSecurity::RAW, RpcSecurity::TLS};
79 }
80
noKernelValues()81 static inline std::vector<bool> noKernelValues() {
82 std::vector<bool> values = {true};
83 if (kEnableKernelIpcTesting) {
84 values.push_back(false);
85 }
86 return values;
87 }
88
hasExperimentalRpc()89 static inline bool hasExperimentalRpc() {
90 #ifdef BINDER_RPC_TO_TRUSTY_TEST
91 // Trusty services do not support the experimental version,
92 // so that we can update the prebuilts separately.
93 // This covers the binderRpcToTrustyTest case on Android.
94 return false;
95 #endif
96 #ifdef __ANDROID__
97 return base::GetProperty("ro.build.version.codename", "") != "REL";
98 #else
99 return false;
100 #endif
101 }
102
testVersions()103 static inline std::vector<uint32_t> testVersions() {
104 std::vector<uint32_t> versions;
105 for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
106 versions.push_back(i);
107 }
108 if (hasExperimentalRpc()) {
109 versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
110 }
111 return versions;
112 }
113
trustyIpcPort(uint32_t serverVersion)114 static inline std::string trustyIpcPort(uint32_t serverVersion) {
115 return "com.android.trusty.binderRpcTestService.V" + std::to_string(serverVersion);
116 }
117
118 enum class SocketType {
119 PRECONNECTED,
120 UNIX,
121 UNIX_BOOTSTRAP,
122 UNIX_RAW,
123 VSOCK,
124 INET,
125 TIPC,
126 };
127
PrintToString(SocketType socketType)128 static inline std::string PrintToString(SocketType socketType) {
129 switch (socketType) {
130 case SocketType::PRECONNECTED:
131 return "preconnected_uds";
132 case SocketType::UNIX:
133 return "unix_domain_socket";
134 case SocketType::UNIX_BOOTSTRAP:
135 return "unix_domain_socket_bootstrap";
136 case SocketType::UNIX_RAW:
137 return "raw_uds";
138 case SocketType::VSOCK:
139 return "vm_socket";
140 case SocketType::INET:
141 return "inet_socket";
142 case SocketType::TIPC:
143 return "trusty_ipc";
144 default:
145 LOG_ALWAYS_FATAL("Unknown socket type");
146 return "";
147 }
148 }
149
epochMillis()150 static inline size_t epochMillis() {
151 using std::chrono::duration_cast;
152 using std::chrono::milliseconds;
153 using std::chrono::seconds;
154 using std::chrono::system_clock;
155 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
156 }
157
158 struct BinderRpcOptions {
159 size_t numThreads = 1;
160 size_t numSessions = 1;
161 // right now, this can be empty, or length numSessions, where each value
162 // represents the info for the corresponding session, but we should
163 // probably switch this to be a list of sessions options so that other
164 // options can all be specified per session
165 std::vector<size_t> numIncomingConnectionsBySession = {};
166 size_t numOutgoingConnections = SIZE_MAX;
167 RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
168 RpcSession::FileDescriptorTransportMode::NONE;
169 std::vector<RpcSession::FileDescriptorTransportMode>
170 serverSupportedFileDescriptorTransportModes = {
171 RpcSession::FileDescriptorTransportMode::NONE};
172
173 // If true, connection failures will result in `ProcessSession::sessions` being empty
174 // instead of a fatal error.
175 bool allowConnectFailure = false;
176 };
177
178 #ifndef __TRUSTY__
writeString(binder::borrowed_fd fd,std::string_view str)179 static inline void writeString(binder::borrowed_fd fd, std::string_view str) {
180 uint64_t length = str.length();
181 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, &length, sizeof(length)));
182 LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, str.data(), str.length()));
183 }
184
readString(binder::borrowed_fd fd)185 static inline std::string readString(binder::borrowed_fd fd) {
186 uint64_t length;
187 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, &length, sizeof(length)));
188 std::string ret(length, '\0');
189 LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, ret.data(), length));
190 return ret;
191 }
192
writeToFd(binder::borrowed_fd fd,const Parcelable & parcelable)193 static inline void writeToFd(binder::borrowed_fd fd, const Parcelable& parcelable) {
194 Parcel parcel;
195 LOG_ALWAYS_FATAL_IF(OK != parcelable.writeToParcel(&parcel));
196 writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
197 }
198
199 template <typename T>
readFromFd(binder::borrowed_fd fd)200 static inline T readFromFd(binder::borrowed_fd fd) {
201 std::string data = readString(fd);
202 Parcel parcel;
203 LOG_ALWAYS_FATAL_IF(OK !=
204 parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
205 T object;
206 LOG_ALWAYS_FATAL_IF(OK != object.readFromParcel(&parcel));
207 return object;
208 }
209
210 static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
211 RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
212 std::unique_ptr<RpcAuth> auth = nullptr) {
213 switch (rpcSecurity) {
214 case RpcSecurity::RAW:
215 return RpcTransportCtxFactoryRaw::make();
216 case RpcSecurity::TLS: {
217 if (verifier == nullptr) {
218 verifier = std::make_shared<RpcCertificateVerifierSimple>();
219 }
220 if (auth == nullptr) {
221 auth = std::make_unique<RpcAuthSelfSigned>();
222 }
223 return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
224 }
225 default:
226 LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", static_cast<int>(rpcSecurity));
227 }
228 }
229
230 // Create an FD that returns `contents` when read.
mockFileDescriptor(std::string contents)231 static inline binder::unique_fd mockFileDescriptor(std::string contents) {
232 binder::unique_fd readFd, writeFd;
233 LOG_ALWAYS_FATAL_IF(!binder::Pipe(&readFd, &writeFd), "%s", strerror(errno));
234 RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
235 signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
236 if (!android::binder::WriteStringToFd(contents, writeFd)) {
237 int savedErrno = errno;
238 LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
239 strerror(savedErrno));
240 }
241 }).detach();
242 return readFd;
243 }
244 #endif // __TRUSTY__
245
246 // A threadsafe channel where writes block until the value is read.
247 template <typename T>
248 class HandoffChannel {
249 public:
write(T v)250 void write(T v) {
251 {
252 RpcMutexUniqueLock lock(mMutex);
253 // Wait for space to send.
254 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
255 mValue.emplace(std::move(v));
256 }
257 mCvFull.notify_all();
258 RpcMutexUniqueLock lock(mMutex);
259 // Wait for it to be taken.
260 mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
261 }
262
read()263 T read() {
264 RpcMutexUniqueLock lock(mMutex);
265 if (!mValue.has_value()) {
266 mCvFull.wait(lock, [&]() { return mValue.has_value(); });
267 }
268 T v = std::move(mValue.value());
269 mValue.reset();
270 lock.unlock();
271 mCvEmpty.notify_all();
272 return v;
273 }
274
275 private:
276 RpcMutex mMutex;
277 RpcConditionVariable mCvEmpty;
278 RpcConditionVariable mCvFull;
279 std::optional<T> mValue;
280 };
281
282 using android::binder::Status;
283
284 class MyBinderRpcSession : public BnBinderRpcSession {
285 public:
286 static std::atomic<int32_t> gNum;
287
MyBinderRpcSession(const std::string & name)288 MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
getName(std::string * name)289 Status getName(std::string* name) override {
290 *name = mName;
291 return Status::ok();
292 }
~MyBinderRpcSession()293 ~MyBinderRpcSession() { gNum--; }
294
295 private:
296 std::string mName;
297 };
298
299 class MyBinderRpcCallback : public BnBinderRpcCallback {
sendCallback(const std::string & value)300 Status sendCallback(const std::string& value) {
301 RpcMutexUniqueLock _l(mMutex);
302 mValues.push_back(value);
303 _l.unlock();
304 mCv.notify_one();
305 return Status::ok();
306 }
sendOnewayCallback(const std::string & value)307 Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
308
309 public:
310 RpcMutex mMutex;
311 RpcConditionVariable mCv;
312 std::vector<std::string> mValues;
313 };
314
315 // Base class for all concrete implementations of MyBinderRpcTest.
316 // Sub-classes that want to provide a full implementation should derive
317 // from this class instead of MyBinderRpcTestDefault below so the compiler
318 // checks that all methods are implemented.
319 class MyBinderRpcTestBase : public BnBinderRpcTest {
320 public:
321 int port = 0;
322
sendString(const std::string & str)323 Status sendString(const std::string& str) override {
324 (void)str;
325 return Status::ok();
326 }
doubleString(const std::string & str,std::string * strstr)327 Status doubleString(const std::string& str, std::string* strstr) override {
328 *strstr = str + str;
329 return Status::ok();
330 }
getClientPort(int * out)331 Status getClientPort(int* out) override {
332 *out = port;
333 return Status::ok();
334 }
getNullBinder(sp<IBinder> * out)335 Status getNullBinder(sp<IBinder>* out) override {
336 out->clear();
337 return Status::ok();
338 }
pingMe(const sp<IBinder> & binder,int32_t * out)339 Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
340 if (binder == nullptr) {
341 std::cout << "Received null binder!" << std::endl;
342 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
343 }
344 *out = binder->pingBinder();
345 return Status::ok();
346 }
repeatBinder(const sp<IBinder> & binder,sp<IBinder> * out)347 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
348 *out = binder;
349 return Status::ok();
350 }
351 static sp<IBinder> mHeldBinder;
holdBinder(const sp<IBinder> & binder)352 Status holdBinder(const sp<IBinder>& binder) override {
353 mHeldBinder = binder;
354 return Status::ok();
355 }
getHeldBinder(sp<IBinder> * held)356 Status getHeldBinder(sp<IBinder>* held) override {
357 *held = mHeldBinder;
358 return Status::ok();
359 }
nestMe(const sp<IBinderRpcTest> & binder,int count)360 Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
361 if (count <= 0) return Status::ok();
362 return binder->nestMe(this, count - 1);
363 }
alwaysGiveMeTheSameBinder(sp<IBinder> * out)364 Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
365 static sp<IBinder> binder = new BBinder;
366 *out = binder;
367 return Status::ok();
368 }
openSession(const std::string & name,sp<IBinderRpcSession> * out)369 Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
370 *out = new MyBinderRpcSession(name);
371 return Status::ok();
372 }
getNumOpenSessions(int32_t * out)373 Status getNumOpenSessions(int32_t* out) override {
374 *out = MyBinderRpcSession::gNum;
375 return Status::ok();
376 }
377
378 RpcMutex blockMutex;
lock()379 Status lock() override {
380 blockMutex.lock();
381 return Status::ok();
382 }
unlockInMsAsync(int32_t ms)383 Status unlockInMsAsync(int32_t ms) override {
384 usleep(ms * 1000);
385 blockMutex.unlock();
386 return Status::ok();
387 }
lockUnlock()388 Status lockUnlock() override {
389 RpcMutexLockGuard _l(blockMutex);
390 return Status::ok();
391 }
392
sleepMs(int32_t ms)393 Status sleepMs(int32_t ms) override {
394 usleep(ms * 1000);
395 return Status::ok();
396 }
397
sleepMsAsync(int32_t ms)398 Status sleepMsAsync(int32_t ms) override {
399 // In-process binder calls are asynchronous, but the call to this method
400 // is synchronous wrt its client. This in/out-process threading model
401 // diffentiation is a classic binder leaky abstraction (for better or
402 // worse) and is preserved here the way binder sockets plugs itself
403 // into BpBinder, as nothing is changed at the higher levels
404 // (IInterface) which result in this behavior.
405 return sleepMs(ms);
406 }
407
doCallback(const sp<IBinderRpcCallback> & callback,bool oneway,bool delayed,const std::string & value)408 Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
409 const std::string& value) override {
410 if (callback == nullptr) {
411 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
412 }
413
414 if (delayed) {
415 RpcMaybeThread([=, this]() {
416 ALOGE("Executing delayed callback: '%s'", value.c_str());
417 Status status = doCallback(callback, oneway, false, value);
418 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
419 }).detach();
420 return Status::ok();
421 }
422
423 if (oneway) {
424 return callback->sendOnewayCallback(value);
425 }
426
427 return callback->sendCallback(value);
428 }
429
doCallbackAsync(const sp<IBinderRpcCallback> & callback,bool oneway,bool delayed,const std::string & value)430 Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
431 const std::string& value) override {
432 return doCallback(callback, oneway, delayed, value);
433 }
434
435 protected:
436 // Generic version of countBinders that works with both
437 // RpcServer and RpcServerTrusty
438 template <typename T>
countBindersImpl(const wp<T> & server,std::vector<int32_t> * out)439 Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
440 sp<T> spServer = server.promote();
441 if (spServer == nullptr) {
442 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
443 }
444 out->clear();
445 for (auto session : spServer->listSessions()) {
446 size_t count = session->state()->countBinders();
447 out->push_back(count);
448 }
449 return Status::ok();
450 }
451 };
452
453 // Default implementation of MyBinderRpcTest that can be used as-is
454 // or derived from by classes that only want to implement a subset of
455 // the unimplemented methods
456 class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
457 public:
countBinders(std::vector<int32_t> *)458 Status countBinders(std::vector<int32_t>* /*out*/) override {
459 return Status::fromStatusT(UNKNOWN_TRANSACTION);
460 }
461
die(bool)462 Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
463
scheduleShutdown()464 Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
465
useKernelBinderCallingId()466 Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
467
echoAsFile(const std::string &,android::os::ParcelFileDescriptor *)468 Status echoAsFile(const std::string& /*content*/,
469 android::os::ParcelFileDescriptor* /*out*/) override {
470 return Status::fromStatusT(UNKNOWN_TRANSACTION);
471 }
472
concatFiles(const std::vector<android::os::ParcelFileDescriptor> &,android::os::ParcelFileDescriptor *)473 Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
474 android::os::ParcelFileDescriptor* /*out*/) override {
475 return Status::fromStatusT(UNKNOWN_TRANSACTION);
476 }
477
blockingSendFdOneway(const android::os::ParcelFileDescriptor &)478 Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
479 return Status::fromStatusT(UNKNOWN_TRANSACTION);
480 }
481
blockingRecvFd(android::os::ParcelFileDescriptor *)482 Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
483 return Status::fromStatusT(UNKNOWN_TRANSACTION);
484 }
485
blockingSendIntOneway(int)486 Status blockingSendIntOneway(int /*n*/) override {
487 return Status::fromStatusT(UNKNOWN_TRANSACTION);
488 }
489
blockingRecvInt(int *)490 Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
491 };
492
493 } // namespace android
494