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