1 /*
2  * Copyright (C) 2018 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 #include <IBinderNdkUnitTest.h>
18 #include <aidl/BnBinderNdkUnitTest.h>
19 #include <aidl/BnEmpty.h>
20 #include <android-base/logging.h>
21 #include <android/binder_ibinder_jni.h>
22 #include <android/binder_ibinder_platform.h>
23 #include <android/binder_manager.h>
24 #include <android/binder_process.h>
25 #include <gtest/gtest.h>
26 #include <iface/iface.h>
27 #include <utils/Looper.h>
28 
29 // warning: this is assuming that libbinder_ndk is using the same copy
30 // of libbinder that we are.
31 #include <binder/IPCThreadState.h>
32 #include <binder/IResultReceiver.h>
33 #include <binder/IServiceManager.h>
34 #include <binder/IShellCallback.h>
35 
36 #include <sys/prctl.h>
37 #include <chrono>
38 #include <condition_variable>
39 #include <iostream>
40 #include <mutex>
41 
42 using namespace android;
43 
44 constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
45 constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
46 
47 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
repeatInt(int32_t in,int32_t * out)48     ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
49         *out = in;
50         return ndk::ScopedAStatus::ok();
51     }
takeInterface(const std::shared_ptr<aidl::IEmpty> & empty)52     ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
53         (void)empty;
54         return ndk::ScopedAStatus::ok();
55     }
forceFlushCommands()56     ndk::ScopedAStatus forceFlushCommands() {
57         // warning: this is assuming that libbinder_ndk is using the same copy
58         // of libbinder that we are.
59         android::IPCThreadState::self()->flushCommands();
60         return ndk::ScopedAStatus::ok();
61     }
getsRequestedSid(bool * out)62     ndk::ScopedAStatus getsRequestedSid(bool* out) {
63         const char* sid = AIBinder_getCallingSid();
64         std::cout << "Got security context: " << (sid ?: "null") << std::endl;
65         *out = sid != nullptr;
66         return ndk::ScopedAStatus::ok();
67     }
handleShellCommand(int,int out,int,const char ** args,uint32_t numArgs)68     binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
69                                        uint32_t numArgs) override {
70         for (uint32_t i = 0; i < numArgs; i++) {
71             dprintf(out, "%s", args[i]);
72         }
73         fsync(out);
74         return STATUS_OK;
75     }
76 };
77 
generatedService()78 int generatedService() {
79     ABinderProcess_setThreadPoolMaxThreadCount(0);
80 
81     auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
82     auto binder = service->asBinder();
83 
84     AIBinder_setRequestingSid(binder.get(), true);
85 
86     binder_status_t status = AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
87 
88     if (status != STATUS_OK) {
89         LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService;
90     }
91 
92     ABinderProcess_joinThreadPool();
93 
94     return 1;  // should not return
95 }
96 
97 // manually-written parceling class considered bad practice
98 class MyFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)99     binder_status_t doubleNumber(int32_t in, int32_t* out) override {
100         *out = 2 * in;
101         LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
102         return STATUS_OK;
103     }
104 
die()105     binder_status_t die() override {
106         LOG(FATAL) << "IFoo::die called!";
107         return STATUS_UNKNOWN_ERROR;
108     }
109 };
110 
manualService(const char * instance)111 void manualService(const char* instance) {
112     // Strong reference to MyFoo kept by service manager.
113     binder_status_t status = (new MyFoo)->addService(instance);
114 
115     if (status != STATUS_OK) {
116         LOG(FATAL) << "Could not register: " << status << " " << instance;
117     }
118 }
manualPollingService(const char * instance)119 int manualPollingService(const char* instance) {
120     int fd;
121     CHECK(STATUS_OK == ABinderProcess_setupPolling(&fd));
122     manualService(instance);
123 
124     class Handler : public LooperCallback {
125         int handleEvent(int /*fd*/, int /*events*/, void* /*data*/) override {
126             ABinderProcess_handlePolledCommands();
127             return 1;  // Continue receiving callbacks.
128         }
129     };
130 
131     sp<Looper> looper = Looper::prepare(0 /* opts */);
132     looper->addFd(fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, new Handler(), nullptr /*data*/);
133     // normally, would add additional fds
134     while (true) {
135         looper->pollAll(-1 /* timeoutMillis */);
136     }
137     return 1;  // should not reach
138 }
manualThreadPoolService(const char * instance)139 int manualThreadPoolService(const char* instance) {
140     ABinderProcess_setThreadPoolMaxThreadCount(0);
141     manualService(instance);
142     ABinderProcess_joinThreadPool();
143     return 1;
144 }
145 
146 // This is too slow
147 // TEST(NdkBinder, GetServiceThatDoesntExist) {
148 //     sp<IFoo> foo = IFoo::getService("asdfghkl;");
149 //     EXPECT_EQ(nullptr, foo.get());
150 // }
151 
TEST(NdkBinder,CheckServiceThatDoesntExist)152 TEST(NdkBinder, CheckServiceThatDoesntExist) {
153     AIBinder* binder = AServiceManager_checkService("asdfghkl;");
154     ASSERT_EQ(nullptr, binder);
155 }
156 
TEST(NdkBinder,CheckServiceThatDoesExist)157 TEST(NdkBinder, CheckServiceThatDoesExist) {
158     AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
159     EXPECT_NE(nullptr, binder);
160     EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
161 
162     AIBinder_decStrong(binder);
163 }
164 
TEST(NdkBinder,DoubleNumber)165 TEST(NdkBinder, DoubleNumber) {
166     sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
167     ASSERT_NE(foo, nullptr);
168 
169     int32_t out;
170     EXPECT_EQ(STATUS_OK, foo->doubleNumber(1, &out));
171     EXPECT_EQ(2, out);
172 }
173 
LambdaOnDeath(void * cookie)174 void LambdaOnDeath(void* cookie) {
175     auto onDeath = static_cast<std::function<void(void)>*>(cookie);
176     (*onDeath)();
177 };
TEST(NdkBinder,DeathRecipient)178 TEST(NdkBinder, DeathRecipient) {
179     using namespace std::chrono_literals;
180 
181     AIBinder* binder;
182     sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor, &binder);
183     ASSERT_NE(nullptr, foo.get());
184     ASSERT_NE(nullptr, binder);
185 
186     std::mutex deathMutex;
187     std::condition_variable deathCv;
188     bool deathRecieved = false;
189 
190     std::function<void(void)> onDeath = [&] {
191         std::cerr << "Binder died (as requested)." << std::endl;
192         deathRecieved = true;
193         deathCv.notify_one();
194     };
195 
196     AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
197 
198     EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&onDeath)));
199 
200     // the binder driver should return this if the service dies during the transaction
201     EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
202 
203     foo = nullptr;
204 
205     std::unique_lock<std::mutex> lock(deathMutex);
206     EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; }));
207     EXPECT_TRUE(deathRecieved);
208 
209     AIBinder_DeathRecipient_delete(recipient);
210     AIBinder_decStrong(binder);
211     binder = nullptr;
212 }
213 
TEST(NdkBinder,RetrieveNonNdkService)214 TEST(NdkBinder, RetrieveNonNdkService) {
215     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
216     ASSERT_NE(nullptr, binder);
217     EXPECT_TRUE(AIBinder_isRemote(binder));
218     EXPECT_TRUE(AIBinder_isAlive(binder));
219     EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
220 
221     AIBinder_decStrong(binder);
222 }
223 
OnBinderDeath(void * cookie)224 void OnBinderDeath(void* cookie) {
225     LOG(ERROR) << "BINDER DIED. COOKIE: " << cookie;
226 }
227 
TEST(NdkBinder,LinkToDeath)228 TEST(NdkBinder, LinkToDeath) {
229     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
230     ASSERT_NE(nullptr, binder);
231 
232     AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
233     ASSERT_NE(nullptr, recipient);
234 
235     EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
236     EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
237     EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
238     EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
239     EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
240 
241     AIBinder_DeathRecipient_delete(recipient);
242     AIBinder_decStrong(binder);
243 }
244 
245 class MyTestFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)246     binder_status_t doubleNumber(int32_t in, int32_t* out) override {
247         *out = 2 * in;
248         LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
249         return STATUS_OK;
250     }
die()251     binder_status_t die() override {
252         ADD_FAILURE() << "die called on local instance";
253         return STATUS_OK;
254     }
255 };
256 
TEST(NdkBinder,GetServiceInProcess)257 TEST(NdkBinder, GetServiceInProcess) {
258     static const char* kInstanceName = "test-get-service-in-process";
259 
260     sp<IFoo> foo = new MyTestFoo;
261     EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName));
262 
263     sp<IFoo> getFoo = IFoo::getService(kInstanceName);
264     EXPECT_EQ(foo.get(), getFoo.get());
265 
266     int32_t out;
267     EXPECT_EQ(STATUS_OK, getFoo->doubleNumber(1, &out));
268     EXPECT_EQ(2, out);
269 }
270 
TEST(NdkBinder,EqualityOfRemoteBinderPointer)271 TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
272     AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
273     ASSERT_NE(nullptr, binderA);
274 
275     AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
276     ASSERT_NE(nullptr, binderB);
277 
278     EXPECT_EQ(binderA, binderB);
279 
280     AIBinder_decStrong(binderA);
281     AIBinder_decStrong(binderB);
282 }
283 
TEST(NdkBinder,ToFromJavaNullptr)284 TEST(NdkBinder, ToFromJavaNullptr) {
285     EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
286     EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
287 }
288 
TEST(NdkBinder,ABpBinderRefCount)289 TEST(NdkBinder, ABpBinderRefCount) {
290     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
291     AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
292 
293     ASSERT_NE(nullptr, binder);
294     EXPECT_EQ(1, AIBinder_debugGetRefCount(binder));
295 
296     AIBinder_decStrong(binder);
297 
298     // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here
299     ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder));
300 
301     AIBinder_Weak_delete(wBinder);
302 }
303 
TEST(NdkBinder,AddServiceMultipleTimes)304 TEST(NdkBinder, AddServiceMultipleTimes) {
305     static const char* kInstanceName1 = "test-multi-1";
306     static const char* kInstanceName2 = "test-multi-2";
307     sp<IFoo> foo = new MyTestFoo;
308     EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName1));
309     EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName2));
310     EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
311 }
312 
TEST(NdkBinder,RequestedSidWorks)313 TEST(NdkBinder, RequestedSidWorks) {
314     ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
315     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
316             aidl::IBinderNdkUnitTest::fromBinder(binder);
317 
318     bool gotSid = false;
319     EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk());
320     EXPECT_TRUE(gotSid);
321 }
322 
TEST(NdkBinder,SentAidlBinderCanBeDestroyed)323 TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
324     static volatile bool destroyed = false;
325     static std::mutex dMutex;
326     static std::condition_variable cv;
327 
328     class MyEmpty : public aidl::BnEmpty {
329         virtual ~MyEmpty() {
330             destroyed = true;
331             cv.notify_one();
332         }
333     };
334 
335     std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
336 
337     ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
338     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
339             aidl::IBinderNdkUnitTest::fromBinder(binder);
340 
341     EXPECT_FALSE(destroyed);
342 
343     service->takeInterface(empty);
344     service->forceFlushCommands();
345     empty = nullptr;
346 
347     // give other binder thread time to process commands
348     {
349         using namespace std::chrono_literals;
350         std::unique_lock<std::mutex> lk(dMutex);
351         cv.wait_for(lk, 1s, [] { return destroyed; });
352     }
353 
354     EXPECT_TRUE(destroyed);
355 }
356 
TEST(NdkBinder,ConvertToPlatformBinder)357 TEST(NdkBinder, ConvertToPlatformBinder) {
358     for (const ndk::SpAIBinder& binder :
359          {// remote
360           ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
361           // local
362           ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
363         // convert to platform binder
364         EXPECT_NE(binder.get(), nullptr);
365         sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
366         EXPECT_NE(platformBinder.get(), nullptr);
367         auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
368         EXPECT_NE(proxy, nullptr);
369 
370         // use platform binder
371         int out;
372         EXPECT_TRUE(proxy->repeatInt(4, &out).isOk());
373         EXPECT_EQ(out, 4);
374 
375         // convert back
376         ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
377         EXPECT_EQ(backBinder.get(), binder.get());
378     }
379 }
380 
381 class MyResultReceiver : public BnResultReceiver {
382    public:
383     Mutex mMutex;
384     Condition mCondition;
385     bool mHaveResult = false;
386     int32_t mResult = 0;
387 
send(int32_t resultCode)388     virtual void send(int32_t resultCode) {
389         AutoMutex _l(mMutex);
390         mResult = resultCode;
391         mHaveResult = true;
392         mCondition.signal();
393     }
394 
waitForResult()395     int32_t waitForResult() {
396         AutoMutex _l(mMutex);
397         while (!mHaveResult) {
398             mCondition.wait(mMutex);
399         }
400         return mResult;
401     }
402 };
403 
404 class MyShellCallback : public BnShellCallback {
405    public:
openFile(const String16 &,const String16 &,const String16 &)406     virtual int openFile(const String16& /*path*/, const String16& /*seLinuxContext*/,
407                          const String16& /*mode*/) {
408         // Empty implementation.
409         return 0;
410     }
411 };
412 
ReadFdToString(int fd,std::string * content)413 bool ReadFdToString(int fd, std::string* content) {
414     char buf[64];
415     ssize_t n;
416     while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
417         content->append(buf, n);
418     }
419     return (n == 0) ? true : false;
420 }
421 
shellCmdToString(sp<IBinder> unitTestService,const std::vector<const char * > & args)422 std::string shellCmdToString(sp<IBinder> unitTestService, const std::vector<const char*>& args) {
423     int inFd[2] = {-1, -1};
424     int outFd[2] = {-1, -1};
425     int errFd[2] = {-1, -1};
426 
427     EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, inFd));
428     EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, outFd));
429     EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, errFd));
430 
431     sp<MyShellCallback> cb = new MyShellCallback();
432     sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
433 
434     Vector<String16> argsVec;
435     for (int i = 0; i < args.size(); i++) {
436         argsVec.add(String16(args[i]));
437     }
438     status_t error = IBinder::shellCommand(unitTestService, inFd[0], outFd[0], errFd[0], argsVec,
439                                            cb, resultReceiver);
440     EXPECT_EQ(error, android::OK);
441 
442     status_t res = resultReceiver->waitForResult();
443     EXPECT_EQ(res, android::OK);
444 
445     close(inFd[0]);
446     close(inFd[1]);
447     close(outFd[0]);
448     close(errFd[0]);
449     close(errFd[1]);
450 
451     std::string ret;
452     EXPECT_TRUE(ReadFdToString(outFd[1], &ret));
453     close(outFd[1]);
454     return ret;
455 }
456 
TEST(NdkBinder,UseHandleShellCommand)457 TEST(NdkBinder, UseHandleShellCommand) {
458     static const sp<android::IServiceManager> sm(android::defaultServiceManager());
459     sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
460 
461     EXPECT_EQ("", shellCmdToString(testService, {}));
462     EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
463     EXPECT_EQ("Hello world!", shellCmdToString(testService, {"Hello ", "world!"}));
464     EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
465 }
466 
main(int argc,char * argv[])467 int main(int argc, char* argv[]) {
468     ::testing::InitGoogleTest(&argc, argv);
469 
470     if (fork() == 0) {
471         prctl(PR_SET_PDEATHSIG, SIGHUP);
472         return manualThreadPoolService(IFoo::kInstanceNameToDieFor);
473     }
474     if (fork() == 0) {
475         prctl(PR_SET_PDEATHSIG, SIGHUP);
476         return manualPollingService(IFoo::kSomeInstanceName);
477     }
478     if (fork() == 0) {
479         prctl(PR_SET_PDEATHSIG, SIGHUP);
480         return generatedService();
481     }
482 
483     ABinderProcess_setThreadPoolMaxThreadCount(1);  // to recieve death notifications/callbacks
484     ABinderProcess_startThreadPool();
485 
486     return RUN_ALL_TESTS();
487 }
488 
489 #include <android/binder_auto_utils.h>
490 #include <android/binder_interface_utils.h>
491 #include <android/binder_parcel_utils.h>
492