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, ¬A);
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, ¬B);
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, ¬A);
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