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