xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderSafeInterfaceTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright 2016 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 <binder/SafeInterface.h>
18 
19 #include <binder/IInterface.h>
20 #include <binder/IPCThreadState.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/Parcel.h>
23 #include <binder/Parcelable.h>
24 #include <binder/ProcessState.h>
25 
26 #pragma clang diagnostic push
27 #pragma clang diagnostic ignored "-Weverything"
28 #include <gtest/gtest.h>
29 #pragma clang diagnostic pop
30 
31 #include <utils/Flattenable.h>
32 #include <utils/LightRefBase.h>
33 #include <utils/NativeHandle.h>
34 
35 #include <cutils/native_handle.h>
36 
37 #include <optional>
38 
39 #include <inttypes.h>
40 #include <sys/eventfd.h>
41 #include <sys/prctl.h>
42 
43 #include <gmock/gmock.h>
44 
45 using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
46 using android::binder::unique_fd;
47 
48 namespace android {
49 namespace tests {
50 
51 static const String16 kServiceName("SafeInterfaceTest");
52 
53 enum class TestEnum : uint32_t {
54     INVALID = 0,
55     INITIAL = 1,
56     FINAL = 2,
57 };
58 
59 // This class serves two purposes:
60 //   1) It ensures that the implementation doesn't require copying or moving the data (for
61 //      efficiency purposes)
62 //   2) It tests that Parcelables can be passed correctly
63 class NoCopyNoMove : public Parcelable {
64 public:
65     NoCopyNoMove() = default;
NoCopyNoMove(int32_t value)66     explicit NoCopyNoMove(int32_t value) : mValue(value) {}
67     ~NoCopyNoMove() override = default;
68 
69     // Not copyable
70     NoCopyNoMove(const NoCopyNoMove&) = delete;
71     NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
72 
73     // Not movable
74     NoCopyNoMove(NoCopyNoMove&&) = delete;
75     NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
76 
77     // Parcelable interface
writeToParcel(Parcel * parcel) const78     status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
readFromParcel(const Parcel * parcel)79     status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
80 
getValue() const81     int32_t getValue() const { return mValue; }
setValue(int32_t value)82     void setValue(int32_t value) { mValue = value; }
83 
84 private:
85     int32_t mValue = 0;
86     __attribute__((unused)) uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
87 };
88 
89 struct TestFlattenable : Flattenable<TestFlattenable> {
90     TestFlattenable() = default;
TestFlattenableandroid::tests::TestFlattenable91     explicit TestFlattenable(int32_t v) : value(v) {}
92 
93     // Flattenable protocol
getFlattenedSizeandroid::tests::TestFlattenable94     size_t getFlattenedSize() const { return sizeof(value); }
getFdCountandroid::tests::TestFlattenable95     size_t getFdCount() const { return 0; }
flattenandroid::tests::TestFlattenable96     status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
97         FlattenableUtils::write(buffer, size, value);
98         return NO_ERROR;
99     }
unflattenandroid::tests::TestFlattenable100     status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
101         FlattenableUtils::read(buffer, size, value);
102         return NO_ERROR;
103     }
104 
105     int32_t value = 0;
106 };
107 
108 struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
109     TestLightFlattenable() = default;
TestLightFlattenableandroid::tests::TestLightFlattenable110     explicit TestLightFlattenable(int32_t v) : value(v) {}
111     int32_t value = 0;
112 };
113 
114 // It seems like this should be able to inherit from TestFlattenable (to avoid duplicating code),
115 // but the SafeInterface logic can't easily be extended to find an indirect Flattenable<T>
116 // base class
117 class TestLightRefBaseFlattenable : public Flattenable<TestLightRefBaseFlattenable>,
118                                     public LightRefBase<TestLightRefBaseFlattenable> {
119 public:
120     TestLightRefBaseFlattenable() = default;
TestLightRefBaseFlattenable(int32_t v)121     explicit TestLightRefBaseFlattenable(int32_t v) : value(v) {}
122 
123     // Flattenable protocol
getFlattenedSize() const124     size_t getFlattenedSize() const { return sizeof(value); }
getFdCount() const125     size_t getFdCount() const { return 0; }
flatten(void * & buffer,size_t & size,int * &,size_t &) const126     status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
127         FlattenableUtils::write(buffer, size, value);
128         return NO_ERROR;
129     }
unflatten(void const * & buffer,size_t & size,int const * &,size_t &)130     status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
131         FlattenableUtils::read(buffer, size, value);
132         return NO_ERROR;
133     }
134 
135     int32_t value = 0;
136 };
137 
138 class TestParcelable : public Parcelable {
139 public:
140     TestParcelable() = default;
TestParcelable(int32_t value)141     explicit TestParcelable(int32_t value) : mValue(value) {}
TestParcelable(const TestParcelable & other)142     TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
TestParcelable(TestParcelable && other)143     TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
144 
145     // Parcelable interface
writeToParcel(Parcel * parcel) const146     status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
readFromParcel(const Parcel * parcel)147     status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
148 
getValue() const149     int32_t getValue() const { return mValue; }
setValue(int32_t value)150     void setValue(int32_t value) { mValue = value; }
151 
152 private:
153     int32_t mValue = 0;
154 };
155 
156 class ExitOnDeath : public IBinder::DeathRecipient {
157 public:
158     ~ExitOnDeath() override = default;
159 
binderDied(const wp<IBinder> &)160     void binderDied(const wp<IBinder>& /*who*/) override {
161         ALOG(LOG_INFO, "ExitOnDeath", "Exiting");
162         exit(0);
163     }
164 };
165 
166 // This callback class is used to test both one-way transactions and that sp<IInterface> can be
167 // passed correctly
168 class ICallback : public IInterface {
169 public:
170     DECLARE_META_INTERFACE(Callback)
171 
172     enum class Tag : uint32_t {
173         OnCallback = IBinder::FIRST_CALL_TRANSACTION,
174         Last,
175     };
176 
177     virtual void onCallback(int32_t aPlusOne) = 0;
178 };
179 
180 class BpCallback : public SafeBpInterface<ICallback> {
181 public:
BpCallback(const sp<IBinder> & impl)182     explicit BpCallback(const sp<IBinder>& impl) : SafeBpInterface<ICallback>(impl, getLogTag()) {}
183 
onCallback(int32_t aPlusOne)184     void onCallback(int32_t aPlusOne) override {
185         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
186         return callRemoteAsync<decltype(&ICallback::onCallback)>(Tag::OnCallback, aPlusOne);
187     }
188 
189 private:
getLogTag()190     static constexpr const char* getLogTag() { return "BpCallback"; }
191 };
192 
193 #pragma clang diagnostic push
194 #pragma clang diagnostic ignored "-Wexit-time-destructors"
195 IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback")
196 #pragma clang diagnostic pop
197 
198 class BnCallback : public SafeBnInterface<ICallback> {
199 public:
BnCallback()200     BnCallback() : SafeBnInterface("BnCallback") {}
201 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)202     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
203                         uint32_t /*flags*/) override {
204         EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
205         EXPECT_LT(code, static_cast<uint32_t>(ICallback::Tag::Last));
206         ICallback::Tag tag = static_cast<ICallback::Tag>(code);
207         switch (tag) {
208             case ICallback::Tag::OnCallback: {
209                 return callLocalAsync(data, reply, &ICallback::onCallback);
210             }
211             case ICallback::Tag::Last:
212                 // Should not be possible because of the asserts at the beginning of the method
213                 [&]() { FAIL(); }();
214                 return UNKNOWN_ERROR;
215         }
216     }
217 };
218 
219 class ISafeInterfaceTest : public IInterface {
220 public:
221     DECLARE_META_INTERFACE(SafeInterfaceTest)
222 
223     enum class Tag : uint32_t {
224         SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
225         ReturnsNoMemory,
226         LogicalNot,
227         LogicalNotVector,
228         ModifyEnum,
229         IncrementFlattenable,
230         IncrementLightFlattenable,
231         IncrementLightRefBaseFlattenable,
232         IncrementNativeHandle,
233         IncrementNoCopyNoMove,
234         IncrementParcelableVector,
235         DoubleString,
236         CallMeBack,
237         IncrementInt32,
238         IncrementUint32,
239         IncrementInt64,
240         IncrementUint64,
241         IncrementFloat,
242         IncrementTwo,
243         Last,
244     };
245 
246     // This is primarily so that the remote service dies when the test does, but it also serves to
247     // test the handling of sp<IBinder> and non-const methods
248     virtual status_t setDeathToken(const sp<IBinder>& token) = 0;
249 
250     // This is the most basic test since it doesn't require parceling any arguments
251     virtual status_t returnsNoMemory() const = 0;
252 
253     // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
254     virtual status_t logicalNot(bool a, bool* notA) const = 0;
255     virtual status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const = 0;
256     virtual status_t modifyEnum(TestEnum a, TestEnum* b) const = 0;
257     virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
258     virtual status_t increment(const TestLightFlattenable& a,
259                                TestLightFlattenable* aPlusOne) const = 0;
260     virtual status_t increment(const sp<TestLightRefBaseFlattenable>& a,
261                                sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
262     virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
263     virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
264     virtual status_t increment(const std::vector<TestParcelable>& a,
265                                std::vector<TestParcelable>* aPlusOne) const = 0;
266     virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
267     // As mentioned above, sp<IBinder> is already tested by setDeathToken
268     virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
269     virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
270     virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
271     virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
272     virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
273     virtual status_t increment(float a, float* aPlusOne) const = 0;
274 
275     // This tests that input/output parameter interleaving works correctly
276     virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
277                                int32_t* bPlusOne) const = 0;
278 };
279 
280 class BpSafeInterfaceTest : public SafeBpInterface<ISafeInterfaceTest> {
281 public:
BpSafeInterfaceTest(const sp<IBinder> & impl)282     explicit BpSafeInterfaceTest(const sp<IBinder>& impl)
283           : SafeBpInterface<ISafeInterfaceTest>(impl, getLogTag()) {}
284 
setDeathToken(const sp<IBinder> & token)285     status_t setDeathToken(const sp<IBinder>& token) override {
286         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
287         return callRemote<decltype(&ISafeInterfaceTest::setDeathToken)>(Tag::SetDeathToken, token);
288     }
returnsNoMemory() const289     status_t returnsNoMemory() const override {
290         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
291         return callRemote<decltype(&ISafeInterfaceTest::returnsNoMemory)>(Tag::ReturnsNoMemory);
292     }
logicalNot(bool a,bool * notA) const293     status_t logicalNot(bool a, bool* notA) const override {
294         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
295         using Signature = status_t (ISafeInterfaceTest::*)(bool, bool*) const;
296         return callRemote<Signature>(Tag::LogicalNot, a, notA);
297     }
logicalNot(const std::vector<bool> & a,std::vector<bool> * notA) const298     status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override {
299         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
300         using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>&,
301                                                            std::vector<bool>*) const;
302         return callRemote<Signature>(Tag::LogicalNotVector, a, notA);
303     }
modifyEnum(TestEnum a,TestEnum * b) const304     status_t modifyEnum(TestEnum a, TestEnum* b) const override {
305         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
306         return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b);
307     }
increment(const TestFlattenable & a,TestFlattenable * aPlusOne) const308     status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
309         using Signature =
310                 status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
311         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
312         return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
313     }
increment(const TestLightFlattenable & a,TestLightFlattenable * aPlusOne) const314     status_t increment(const TestLightFlattenable& a,
315                        TestLightFlattenable* aPlusOne) const override {
316         using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
317                                                            TestLightFlattenable*) const;
318         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
319         return callRemote<Signature>(Tag::IncrementLightFlattenable, a, aPlusOne);
320     }
increment(const sp<TestLightRefBaseFlattenable> & a,sp<TestLightRefBaseFlattenable> * aPlusOne) const321     status_t increment(const sp<TestLightRefBaseFlattenable>& a,
322                        sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
323         using Signature = status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
324                                                            sp<TestLightRefBaseFlattenable>*) const;
325         return callRemote<Signature>(Tag::IncrementLightRefBaseFlattenable, a, aPlusOne);
326     }
increment(const sp<NativeHandle> & a,sp<NativeHandle> * aPlusOne) const327     status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
328         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
329         using Signature =
330                 status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&, sp<NativeHandle>*) const;
331         return callRemote<Signature>(Tag::IncrementNativeHandle, a, aPlusOne);
332     }
increment(const NoCopyNoMove & a,NoCopyNoMove * aPlusOne) const333     status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
334         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
335         using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
336                                                            NoCopyNoMove* aPlusOne) const;
337         return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
338     }
increment(const std::vector<TestParcelable> & a,std::vector<TestParcelable> * aPlusOne) const339     status_t increment(const std::vector<TestParcelable>& a,
340                        std::vector<TestParcelable>* aPlusOne) const override {
341         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
342         using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
343                                                            std::vector<TestParcelable>*);
344         return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
345     }
doubleString(const String8 & str,String8 * doubleStr) const346     status_t doubleString(const String8& str, String8* doubleStr) const override {
347         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
348         return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
349                                                                        doubleStr);
350     }
callMeBack(const sp<ICallback> & callback,int32_t a) const351     void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
352         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
353         return callRemoteAsync<decltype(&ISafeInterfaceTest::callMeBack)>(Tag::CallMeBack, callback,
354                                                                           a);
355     }
increment(int32_t a,int32_t * aPlusOne) const356     status_t increment(int32_t a, int32_t* aPlusOne) const override {
357         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
358         using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
359         return callRemote<Signature>(Tag::IncrementInt32, a, aPlusOne);
360     }
increment(uint32_t a,uint32_t * aPlusOne) const361     status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
362         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
363         using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
364         return callRemote<Signature>(Tag::IncrementUint32, a, aPlusOne);
365     }
increment(int64_t a,int64_t * aPlusOne) const366     status_t increment(int64_t a, int64_t* aPlusOne) const override {
367         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
368         using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
369         return callRemote<Signature>(Tag::IncrementInt64, a, aPlusOne);
370     }
increment(uint64_t a,uint64_t * aPlusOne) const371     status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
372         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
373         using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
374         return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
375     }
increment(float a,float * aPlusOne) const376     status_t increment(float a, float* aPlusOne) const override {
377         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
378         using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
379         return callRemote<Signature>(Tag::IncrementFloat, a, aPlusOne);
380     }
increment(int32_t a,int32_t * aPlusOne,int32_t b,int32_t * bPlusOne) const381     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
382         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
383         using Signature =
384                 status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t, int32_t*) const;
385         return callRemote<Signature>(Tag::IncrementTwo, a, aPlusOne, b, bPlusOne);
386     }
387 
388 private:
getLogTag()389     static constexpr const char* getLogTag() { return "BpSafeInterfaceTest"; }
390 };
391 
392 #pragma clang diagnostic push
393 #pragma clang diagnostic ignored "-Wexit-time-destructors"
394 IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest")
395 
getDeathRecipient()396 static sp<IBinder::DeathRecipient> getDeathRecipient() {
397     static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
398     return recipient;
399 }
400 #pragma clang diagnostic pop
401 
402 class BnSafeInterfaceTest : public SafeBnInterface<ISafeInterfaceTest> {
403 public:
BnSafeInterfaceTest()404     BnSafeInterfaceTest() : SafeBnInterface(getLogTag()) {}
405 
setDeathToken(const sp<IBinder> & token)406     status_t setDeathToken(const sp<IBinder>& token) override {
407         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
408         token->linkToDeath(getDeathRecipient());
409         return NO_ERROR;
410     }
returnsNoMemory() const411     status_t returnsNoMemory() const override {
412         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
413         return NO_MEMORY;
414     }
logicalNot(bool a,bool * notA) const415     status_t logicalNot(bool a, bool* notA) const override {
416         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
417         *notA = !a;
418         return NO_ERROR;
419     }
logicalNot(const std::vector<bool> & a,std::vector<bool> * notA) const420     status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override {
421         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
422         notA->clear();
423         for (bool value : a) {
424             notA->push_back(!value);
425         }
426         return NO_ERROR;
427     }
modifyEnum(TestEnum a,TestEnum * b) const428     status_t modifyEnum(TestEnum a, TestEnum* b) const override {
429         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
430         *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID;
431         return NO_ERROR;
432     }
increment(const TestFlattenable & a,TestFlattenable * aPlusOne) const433     status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
434         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
435         aPlusOne->value = a.value + 1;
436         return NO_ERROR;
437     }
increment(const TestLightFlattenable & a,TestLightFlattenable * aPlusOne) const438     status_t increment(const TestLightFlattenable& a,
439                        TestLightFlattenable* aPlusOne) const override {
440         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
441         aPlusOne->value = a.value + 1;
442         return NO_ERROR;
443     }
increment(const sp<TestLightRefBaseFlattenable> & a,sp<TestLightRefBaseFlattenable> * aPlusOne) const444     status_t increment(const sp<TestLightRefBaseFlattenable>& a,
445                        sp<TestLightRefBaseFlattenable>* aPlusOne) const override {
446         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
447         *aPlusOne = new TestLightRefBaseFlattenable(a->value + 1);
448         return NO_ERROR;
449     }
increment(const sp<NativeHandle> & a,sp<NativeHandle> * aPlusOne) const450     status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const override {
451         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
452         native_handle* rawHandle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
453         if (rawHandle == nullptr) return NO_MEMORY;
454 
455         // Copy the fd over directly
456         rawHandle->data[0] = dup(a->handle()->data[0]);
457 
458         // Increment the int
459         rawHandle->data[1] = a->handle()->data[1] + 1;
460 
461         // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
462         // the native_handle when it goes out of scope
463         *aPlusOne = NativeHandle::create(rawHandle, true);
464         return NO_ERROR;
465     }
increment(const NoCopyNoMove & a,NoCopyNoMove * aPlusOne) const466     status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const override {
467         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
468         aPlusOne->setValue(a.getValue() + 1);
469         return NO_ERROR;
470     }
increment(const std::vector<TestParcelable> & a,std::vector<TestParcelable> * aPlusOne) const471     status_t increment(const std::vector<TestParcelable>& a,
472                        std::vector<TestParcelable>* aPlusOne) const override {
473         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
474         aPlusOne->resize(a.size());
475         for (size_t i = 0; i < a.size(); ++i) {
476             (*aPlusOne)[i].setValue(a[i].getValue() + 1);
477         }
478         return NO_ERROR;
479     }
doubleString(const String8 & str,String8 * doubleStr) const480     status_t doubleString(const String8& str, String8* doubleStr) const override {
481         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
482         *doubleStr = str + str;
483         return NO_ERROR;
484     }
callMeBack(const sp<ICallback> & callback,int32_t a) const485     void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
486         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
487         callback->onCallback(a + 1);
488     }
increment(int32_t a,int32_t * aPlusOne) const489     status_t increment(int32_t a, int32_t* aPlusOne) const override {
490         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
491         *aPlusOne = a + 1;
492         return NO_ERROR;
493     }
increment(uint32_t a,uint32_t * aPlusOne) const494     status_t increment(uint32_t a, uint32_t* aPlusOne) const override {
495         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
496         *aPlusOne = a + 1;
497         return NO_ERROR;
498     }
increment(int64_t a,int64_t * aPlusOne) const499     status_t increment(int64_t a, int64_t* aPlusOne) const override {
500         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
501         *aPlusOne = a + 1;
502         return NO_ERROR;
503     }
increment(uint64_t a,uint64_t * aPlusOne) const504     status_t increment(uint64_t a, uint64_t* aPlusOne) const override {
505         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
506         *aPlusOne = a + 1;
507         return NO_ERROR;
508     }
increment(float a,float * aPlusOne) const509     status_t increment(float a, float* aPlusOne) const override {
510         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
511         *aPlusOne = a + 1.0f;
512         return NO_ERROR;
513     }
increment(int32_t a,int32_t * aPlusOne,int32_t b,int32_t * bPlusOne) const514     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
515         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
516         *aPlusOne = a + 1;
517         *bPlusOne = b + 1;
518         return NO_ERROR;
519     }
520 
521     // BnInterface
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)522     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
523                         uint32_t /*flags*/) override {
524         EXPECT_GE(code, IBinder::FIRST_CALL_TRANSACTION);
525         EXPECT_LT(code, static_cast<uint32_t>(Tag::Last));
526         ISafeInterfaceTest::Tag tag = static_cast<ISafeInterfaceTest::Tag>(code);
527         switch (tag) {
528             case ISafeInterfaceTest::Tag::SetDeathToken: {
529                 return callLocal(data, reply, &ISafeInterfaceTest::setDeathToken);
530             }
531             case ISafeInterfaceTest::Tag::ReturnsNoMemory: {
532                 return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory);
533             }
534             case ISafeInterfaceTest::Tag::LogicalNot: {
535                 using Signature = status_t (ISafeInterfaceTest::*)(bool a, bool* notA) const;
536                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot);
537             }
538             case ISafeInterfaceTest::Tag::LogicalNotVector: {
539                 using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>& a,
540                                                                    std::vector<bool>* notA) const;
541                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot);
542             }
543             case ISafeInterfaceTest::Tag::ModifyEnum: {
544                 return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum);
545             }
546             case ISafeInterfaceTest::Tag::IncrementFlattenable: {
547                 using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
548                                                                    TestFlattenable* aPlusOne) const;
549                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
550             }
551             case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
552                 using Signature =
553                         status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
554                                                          TestLightFlattenable* aPlusOne) const;
555                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
556             }
557             case ISafeInterfaceTest::Tag::IncrementLightRefBaseFlattenable: {
558                 using Signature =
559                         status_t (ISafeInterfaceTest::*)(const sp<TestLightRefBaseFlattenable>&,
560                                                          sp<TestLightRefBaseFlattenable>*) const;
561                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
562             }
563             case ISafeInterfaceTest::Tag::IncrementNativeHandle: {
564                 using Signature = status_t (ISafeInterfaceTest::*)(const sp<NativeHandle>&,
565                                                                    sp<NativeHandle>*) const;
566                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
567             }
568             case ISafeInterfaceTest::Tag::IncrementNoCopyNoMove: {
569                 using Signature = status_t (ISafeInterfaceTest::*)(const NoCopyNoMove& a,
570                                                                    NoCopyNoMove* aPlusOne) const;
571                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
572             }
573             case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
574                 using Signature =
575                         status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
576                                                          std::vector<TestParcelable>*) const;
577                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
578             }
579             case ISafeInterfaceTest::Tag::DoubleString: {
580                 return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
581             }
582             case ISafeInterfaceTest::Tag::CallMeBack: {
583                 return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
584             }
585             case ISafeInterfaceTest::Tag::IncrementInt32: {
586                 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*) const;
587                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
588             }
589             case ISafeInterfaceTest::Tag::IncrementUint32: {
590                 using Signature = status_t (ISafeInterfaceTest::*)(uint32_t, uint32_t*) const;
591                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
592             }
593             case ISafeInterfaceTest::Tag::IncrementInt64: {
594                 using Signature = status_t (ISafeInterfaceTest::*)(int64_t, int64_t*) const;
595                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
596             }
597             case ISafeInterfaceTest::Tag::IncrementUint64: {
598                 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
599                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
600             }
601             case ISafeInterfaceTest::Tag::IncrementFloat: {
602                 using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
603                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
604             }
605             case ISafeInterfaceTest::Tag::IncrementTwo: {
606                 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
607                                                                    int32_t*) const;
608                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
609             }
610             case ISafeInterfaceTest::Tag::Last:
611                 // Should not be possible because of the asserts at the beginning of the method
612                 [&]() { FAIL(); }();
613                 return UNKNOWN_ERROR;
614         }
615     }
616 
617 private:
getLogTag()618     static constexpr const char* getLogTag() { return "BnSafeInterfaceTest"; }
619 };
620 
621 class SafeInterfaceTest : public ::testing::Test {
622 public:
SafeInterfaceTest()623     SafeInterfaceTest() : mSafeInterfaceTest(getRemoteService()) {
624         ProcessState::self()->startThreadPool();
625     }
626     ~SafeInterfaceTest() override = default;
627 
628 protected:
629     sp<ISafeInterfaceTest> mSafeInterfaceTest;
630 
631 private:
getLogTag()632     static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
633 
getRemoteService()634     sp<ISafeInterfaceTest> getRemoteService() {
635 #pragma clang diagnostic push
636 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
637         sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
638 #pragma clang diagnostic pop
639         sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
640         EXPECT_TRUE(iface != nullptr);
641 
642         iface->setDeathToken(new BBinder);
643 
644         return iface;
645     }
646 };
647 
TEST_F(SafeInterfaceTest,TestReturnsNoMemory)648 TEST_F(SafeInterfaceTest, TestReturnsNoMemory) {
649     status_t result = mSafeInterfaceTest->returnsNoMemory();
650     ASSERT_EQ(NO_MEMORY, result);
651 }
652 
TEST_F(SafeInterfaceTest,TestLogicalNot)653 TEST_F(SafeInterfaceTest, TestLogicalNot) {
654     const bool a = true;
655     bool notA = true;
656     status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
657     ASSERT_EQ(NO_ERROR, result);
658     ASSERT_EQ(!a, notA);
659     // Test both since we don't want to accidentally catch a default false somewhere
660     const bool b = false;
661     bool notB = false;
662     result = mSafeInterfaceTest->logicalNot(b, &notB);
663     ASSERT_EQ(NO_ERROR, result);
664     ASSERT_EQ(!b, notB);
665 }
666 
TEST_F(SafeInterfaceTest,TestLogicalNotVector)667 TEST_F(SafeInterfaceTest, TestLogicalNotVector) {
668     const std::vector<bool> a = {true, false, true};
669     std::vector<bool> notA;
670     status_t result = mSafeInterfaceTest->logicalNot(a, &notA);
671     ASSERT_EQ(NO_ERROR, result);
672     std::vector<bool> expected = {false, true, false};
673     ASSERT_THAT(notA, testing::ContainerEq(expected));
674 }
675 
TEST_F(SafeInterfaceTest,TestModifyEnum)676 TEST_F(SafeInterfaceTest, TestModifyEnum) {
677     const TestEnum a = TestEnum::INITIAL;
678     TestEnum b = TestEnum::INVALID;
679     status_t result = mSafeInterfaceTest->modifyEnum(a, &b);
680     ASSERT_EQ(NO_ERROR, result);
681     ASSERT_EQ(TestEnum::FINAL, b);
682 }
683 
TEST_F(SafeInterfaceTest,TestIncrementFlattenable)684 TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
685     const TestFlattenable a{1};
686     TestFlattenable aPlusOne{0};
687     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
688     ASSERT_EQ(NO_ERROR, result);
689     ASSERT_EQ(a.value + 1, aPlusOne.value);
690 }
691 
TEST_F(SafeInterfaceTest,TestIncrementLightFlattenable)692 TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
693     const TestLightFlattenable a{1};
694     TestLightFlattenable aPlusOne{0};
695     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
696     ASSERT_EQ(NO_ERROR, result);
697     ASSERT_EQ(a.value + 1, aPlusOne.value);
698 }
699 
TEST_F(SafeInterfaceTest,TestIncrementLightRefBaseFlattenable)700 TEST_F(SafeInterfaceTest, TestIncrementLightRefBaseFlattenable) {
701     sp<TestLightRefBaseFlattenable> a = new TestLightRefBaseFlattenable{1};
702     sp<TestLightRefBaseFlattenable> aPlusOne;
703     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
704     ASSERT_EQ(NO_ERROR, result);
705     ASSERT_NE(nullptr, aPlusOne.get());
706     ASSERT_EQ(a->value + 1, aPlusOne->value);
707 }
708 
709 namespace { // Anonymous namespace
710 
fdsAreEquivalent(int a,int b)711 bool fdsAreEquivalent(int a, int b) {
712     struct stat statA {};
713     struct stat statB {};
714     if (fstat(a, &statA) != 0) return false;
715     if (fstat(b, &statB) != 0) return false;
716     return (statA.st_dev == statB.st_dev) && (statA.st_ino == statB.st_ino);
717 }
718 
719 } // Anonymous namespace
720 
TEST_F(SafeInterfaceTest,TestIncrementNativeHandle)721 TEST_F(SafeInterfaceTest, TestIncrementNativeHandle) {
722     // Create an fd we can use to send and receive from the remote process
723     unique_fd eventFd{eventfd(0 /*initval*/, 0 /*flags*/)};
724     ASSERT_NE(-1, eventFd);
725 
726     // Determine the maximum number of fds this process can have open
727     struct rlimit limit {};
728     ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &limit));
729     uint64_t maxFds = limit.rlim_cur;
730 
731     ALOG(LOG_INFO, "SafeInterfaceTest", "%s max FDs: %" PRIu64, __PRETTY_FUNCTION__, maxFds);
732 
733     // Perform this test enough times to rule out fd leaks
734     for (uint32_t iter = 0; iter < (maxFds + 100); ++iter) {
735         native_handle* handle = native_handle_create(1 /*numFds*/, 1 /*numInts*/);
736         ASSERT_NE(nullptr, handle);
737         handle->data[0] = dup(eventFd.get());
738         handle->data[1] = 1;
739 
740         // This cannot fail, as it is just the sp<NativeHandle> taking responsibility for closing
741         // the native_handle when it goes out of scope
742         sp<NativeHandle> a = NativeHandle::create(handle, true);
743 
744         sp<NativeHandle> aPlusOne;
745         status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
746         ASSERT_EQ(NO_ERROR, result);
747         ASSERT_TRUE(fdsAreEquivalent(a->handle()->data[0], aPlusOne->handle()->data[0]));
748         ASSERT_EQ(a->handle()->data[1] + 1, aPlusOne->handle()->data[1]);
749     }
750 }
751 
TEST_F(SafeInterfaceTest,TestIncrementNoCopyNoMove)752 TEST_F(SafeInterfaceTest, TestIncrementNoCopyNoMove) {
753     const NoCopyNoMove a{1};
754     NoCopyNoMove aPlusOne{0};
755     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
756     ASSERT_EQ(NO_ERROR, result);
757     ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
758 }
759 
TEST_F(SafeInterfaceTest,TestIncrementParcelableVector)760 TEST_F(SafeInterfaceTest, TestIncrementParcelableVector) {
761     const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
762     std::vector<TestParcelable> aPlusOne;
763     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
764     ASSERT_EQ(NO_ERROR, result);
765     ASSERT_EQ(a.size(), aPlusOne.size());
766     for (size_t i = 0; i < a.size(); ++i) {
767         ASSERT_EQ(a[i].getValue() + 1, aPlusOne[i].getValue());
768     }
769 }
770 
TEST_F(SafeInterfaceTest,TestDoubleString)771 TEST_F(SafeInterfaceTest, TestDoubleString) {
772     const String8 str{"asdf"};
773     String8 doubleStr;
774     status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
775     ASSERT_EQ(NO_ERROR, result);
776     ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
777 }
778 
TEST_F(SafeInterfaceTest,TestCallMeBack)779 TEST_F(SafeInterfaceTest, TestCallMeBack) {
780     class CallbackReceiver : public BnCallback {
781     public:
782         void onCallback(int32_t aPlusOne) override {
783             ALOG(LOG_INFO, "CallbackReceiver", "%s", __PRETTY_FUNCTION__);
784             std::unique_lock<decltype(mMutex)> lock(mMutex);
785             mValue = aPlusOne;
786             mCondition.notify_one();
787         }
788 
789         std::optional<int32_t> waitForCallback() {
790             std::unique_lock<decltype(mMutex)> lock(mMutex);
791             bool success =
792                     mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); });
793             return success ? mValue : std::nullopt;
794         }
795 
796     private:
797         std::mutex mMutex;
798         std::condition_variable mCondition;
799         std::optional<int32_t> mValue;
800     };
801 
802     sp<CallbackReceiver> receiver = new CallbackReceiver;
803     const int32_t a = 1;
804     mSafeInterfaceTest->callMeBack(receiver, a);
805     auto result = receiver->waitForCallback();
806     ASSERT_TRUE(result);
807     ASSERT_EQ(a + 1, *result);
808 }
809 
TEST_F(SafeInterfaceTest,TestIncrementInt32)810 TEST_F(SafeInterfaceTest, TestIncrementInt32) {
811     const int32_t a = 1;
812     int32_t aPlusOne = 0;
813     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
814     ASSERT_EQ(NO_ERROR, result);
815     ASSERT_EQ(a + 1, aPlusOne);
816 }
817 
TEST_F(SafeInterfaceTest,TestIncrementUint32)818 TEST_F(SafeInterfaceTest, TestIncrementUint32) {
819     const uint32_t a = 1;
820     uint32_t aPlusOne = 0;
821     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
822     ASSERT_EQ(NO_ERROR, result);
823     ASSERT_EQ(a + 1, aPlusOne);
824 }
825 
TEST_F(SafeInterfaceTest,TestIncrementInt64)826 TEST_F(SafeInterfaceTest, TestIncrementInt64) {
827     const int64_t a = 1;
828     int64_t aPlusOne = 0;
829     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
830     ASSERT_EQ(NO_ERROR, result);
831     ASSERT_EQ(a + 1, aPlusOne);
832 }
833 
TEST_F(SafeInterfaceTest,TestIncrementUint64)834 TEST_F(SafeInterfaceTest, TestIncrementUint64) {
835     const uint64_t a = 1;
836     uint64_t aPlusOne = 0;
837     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
838     ASSERT_EQ(NO_ERROR, result);
839     ASSERT_EQ(a + 1, aPlusOne);
840 }
841 
TEST_F(SafeInterfaceTest,TestIncrementFloat)842 TEST_F(SafeInterfaceTest, TestIncrementFloat) {
843     const float a = 1.0f;
844     float aPlusOne = 0.0f;
845     status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
846     ASSERT_EQ(NO_ERROR, result);
847     ASSERT_EQ(a + 1.0f, aPlusOne);
848 }
849 
TEST_F(SafeInterfaceTest,TestIncrementTwo)850 TEST_F(SafeInterfaceTest, TestIncrementTwo) {
851     const int32_t a = 1;
852     int32_t aPlusOne = 0;
853     const int32_t b = 2;
854     int32_t bPlusOne = 0;
855     status_t result = mSafeInterfaceTest->increment(1, &aPlusOne, 2, &bPlusOne);
856     ASSERT_EQ(NO_ERROR, result);
857     ASSERT_EQ(a + 1, aPlusOne);
858     ASSERT_EQ(b + 1, bPlusOne);
859 }
860 
main(int argc,char ** argv)861 extern "C" int main(int argc, char **argv) {
862     testing::InitGoogleTest(&argc, argv);
863 
864     if (fork() == 0) {
865         prctl(PR_SET_PDEATHSIG, SIGHUP);
866         sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
867         status_t status = defaultServiceManager()->addService(kServiceName, nativeService);
868         if (status != OK) {
869             ALOG(LOG_INFO, "SafeInterfaceServer", "could not register");
870             return EXIT_FAILURE;
871         }
872         IPCThreadState::self()->joinThreadPool();
873         return EXIT_FAILURE;
874     }
875 
876     return RUN_ALL_TESTS();
877 }
878 
879 } // namespace tests
880 } // namespace android
881