1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/android/binder.h"
6
7 #include <android/binder_ibinder.h>
8 #include <android/binder_ibinder_jni.h>
9 #include <android/binder_parcel.h>
10 #include <android/binder_status.h>
11 #include <dlfcn.h>
12
13 #include <cstdint>
14 #include <memory>
15 #include <tuple>
16 #include <utility>
17 #include <vector>
18
19 #include "base/android/requires_api.h"
20 #include "base/check.h"
21 #include "base/memory/raw_ptr_exclusion.h"
22 #include "base/no_destructor.h"
23 #include "base/notreached.h"
24 #include "base/numerics/safe_conversions.h"
25 #include "base/types/expected.h"
26
27 // The Binder NDK library was introduced in Q.
28 #define BINDER_MIN_API 29
29
30 // Helper used extensively herein to guard blocks of code on the availability of
31 // Binder NDK functions.
32 #define WITH_BINDER_API(name) \
33 if (__builtin_available(android BINDER_MIN_API, *)) \
34 if (GetBinderApi()) \
35 if (const BinderApi& name = *GetBinderApi(); true)
36
37 namespace base::android {
38
39 namespace {
40
41 // Helper to expose useful functions from libbinder_ndk.so at runtime. Currently
42 // limited to functions supported in Q.
43 struct BASE_EXPORT BinderApi {
44 // Excluded from raw_ptr because this is trivially safe and it keeps BinderApi
45 // from having a destructor in any build configuration.
46 RAW_PTR_EXCLUSION void* const library = dlopen("libbinder_ndk.so", RTLD_LAZY);
47
48 #define DEFINE_BINDER_API_ENTRY(name) \
49 REQUIRES_ANDROID_API(BINDER_MIN_API) \
50 decltype(::name)* const name = \
51 library ? (decltype(::name)*)dlsym(library, "" #name) : nullptr
52
53 DEFINE_BINDER_API_ENTRY(AIBinder_Class_define);
54 DEFINE_BINDER_API_ENTRY(AIBinder_Class_setOnDump);
55 DEFINE_BINDER_API_ENTRY(AIBinder_new);
56 DEFINE_BINDER_API_ENTRY(AIBinder_isRemote);
57 DEFINE_BINDER_API_ENTRY(AIBinder_isAlive);
58 DEFINE_BINDER_API_ENTRY(AIBinder_ping);
59 DEFINE_BINDER_API_ENTRY(AIBinder_dump);
60 DEFINE_BINDER_API_ENTRY(AIBinder_linkToDeath);
61 DEFINE_BINDER_API_ENTRY(AIBinder_unlinkToDeath);
62 DEFINE_BINDER_API_ENTRY(AIBinder_getCallingUid);
63 DEFINE_BINDER_API_ENTRY(AIBinder_getCallingPid);
64 DEFINE_BINDER_API_ENTRY(AIBinder_incStrong);
65 DEFINE_BINDER_API_ENTRY(AIBinder_decStrong);
66 DEFINE_BINDER_API_ENTRY(AIBinder_debugGetRefCount);
67 DEFINE_BINDER_API_ENTRY(AIBinder_associateClass);
68 DEFINE_BINDER_API_ENTRY(AIBinder_getClass);
69 DEFINE_BINDER_API_ENTRY(AIBinder_getUserData);
70 DEFINE_BINDER_API_ENTRY(AIBinder_prepareTransaction);
71 DEFINE_BINDER_API_ENTRY(AIBinder_transact);
72 DEFINE_BINDER_API_ENTRY(AIBinder_Weak_new);
73 DEFINE_BINDER_API_ENTRY(AIBinder_Weak_delete);
74 DEFINE_BINDER_API_ENTRY(AIBinder_Weak_promote);
75 DEFINE_BINDER_API_ENTRY(AIBinder_DeathRecipient_new);
76 DEFINE_BINDER_API_ENTRY(AIBinder_DeathRecipient_delete);
77 DEFINE_BINDER_API_ENTRY(AIBinder_fromJavaBinder);
78 DEFINE_BINDER_API_ENTRY(AIBinder_toJavaBinder);
79 DEFINE_BINDER_API_ENTRY(AParcel_delete);
80 DEFINE_BINDER_API_ENTRY(AParcel_setDataPosition);
81 DEFINE_BINDER_API_ENTRY(AParcel_getDataPosition);
82 DEFINE_BINDER_API_ENTRY(AParcel_writeStrongBinder);
83 DEFINE_BINDER_API_ENTRY(AParcel_readStrongBinder);
84 DEFINE_BINDER_API_ENTRY(AParcel_writeParcelFileDescriptor);
85 DEFINE_BINDER_API_ENTRY(AParcel_readParcelFileDescriptor);
86 DEFINE_BINDER_API_ENTRY(AParcel_writeStatusHeader);
87 DEFINE_BINDER_API_ENTRY(AParcel_readStatusHeader);
88 DEFINE_BINDER_API_ENTRY(AParcel_writeString);
89 DEFINE_BINDER_API_ENTRY(AParcel_readString);
90 DEFINE_BINDER_API_ENTRY(AParcel_writeStringArray);
91 DEFINE_BINDER_API_ENTRY(AParcel_readStringArray);
92 DEFINE_BINDER_API_ENTRY(AParcel_writeParcelableArray);
93 DEFINE_BINDER_API_ENTRY(AParcel_readParcelableArray);
94 DEFINE_BINDER_API_ENTRY(AParcel_writeInt32);
95 DEFINE_BINDER_API_ENTRY(AParcel_writeUint32);
96 DEFINE_BINDER_API_ENTRY(AParcel_writeInt64);
97 DEFINE_BINDER_API_ENTRY(AParcel_writeUint64);
98 DEFINE_BINDER_API_ENTRY(AParcel_writeFloat);
99 DEFINE_BINDER_API_ENTRY(AParcel_writeDouble);
100 DEFINE_BINDER_API_ENTRY(AParcel_writeBool);
101 DEFINE_BINDER_API_ENTRY(AParcel_writeChar);
102 DEFINE_BINDER_API_ENTRY(AParcel_writeByte);
103 DEFINE_BINDER_API_ENTRY(AParcel_readInt32);
104 DEFINE_BINDER_API_ENTRY(AParcel_readUint32);
105 DEFINE_BINDER_API_ENTRY(AParcel_readInt64);
106 DEFINE_BINDER_API_ENTRY(AParcel_readUint64);
107 DEFINE_BINDER_API_ENTRY(AParcel_readFloat);
108 DEFINE_BINDER_API_ENTRY(AParcel_readDouble);
109 DEFINE_BINDER_API_ENTRY(AParcel_readBool);
110 DEFINE_BINDER_API_ENTRY(AParcel_readChar);
111 DEFINE_BINDER_API_ENTRY(AParcel_readByte);
112 DEFINE_BINDER_API_ENTRY(AParcel_writeInt32Array);
113 DEFINE_BINDER_API_ENTRY(AParcel_writeUint32Array);
114 DEFINE_BINDER_API_ENTRY(AParcel_writeInt64Array);
115 DEFINE_BINDER_API_ENTRY(AParcel_writeUint64Array);
116 DEFINE_BINDER_API_ENTRY(AParcel_writeFloatArray);
117 DEFINE_BINDER_API_ENTRY(AParcel_writeDoubleArray);
118 DEFINE_BINDER_API_ENTRY(AParcel_writeBoolArray);
119 DEFINE_BINDER_API_ENTRY(AParcel_writeCharArray);
120 DEFINE_BINDER_API_ENTRY(AParcel_writeByteArray);
121 DEFINE_BINDER_API_ENTRY(AParcel_readInt32Array);
122 DEFINE_BINDER_API_ENTRY(AParcel_readUint32Array);
123 DEFINE_BINDER_API_ENTRY(AParcel_readInt64Array);
124 DEFINE_BINDER_API_ENTRY(AParcel_readUint64Array);
125 DEFINE_BINDER_API_ENTRY(AParcel_readFloatArray);
126 DEFINE_BINDER_API_ENTRY(AParcel_readDoubleArray);
127 DEFINE_BINDER_API_ENTRY(AParcel_readBoolArray);
128 DEFINE_BINDER_API_ENTRY(AParcel_readCharArray);
129 DEFINE_BINDER_API_ENTRY(AParcel_readByteArray);
130 #undef DEFINE_BINDER_API_ENTRY
131 };
132
GetBinderApi()133 static BinderApi* GetBinderApi() {
134 static BinderApi api;
135 if (!api.library) {
136 return nullptr;
137 }
138 return &api;
139 }
140
BindersFromParent()141 std::unique_ptr<std::vector<BinderRef>>& BindersFromParent() {
142 static NoDestructor<std::unique_ptr<std::vector<BinderRef>>> ptr;
143 return *ptr;
144 }
145
146 } // namespace
147
ParcelReader(const AParcel * parcel)148 ParcelReader::ParcelReader(const AParcel* parcel) : parcel_(parcel) {}
149
ParcelReader(const Parcel & parcel)150 ParcelReader::ParcelReader(const Parcel& parcel) : parcel_(parcel.get()) {}
151
152 ParcelReader::ParcelReader(const ParcelReader&) = default;
153
154 ParcelReader& ParcelReader::operator=(const ParcelReader&) = default;
155
156 ParcelReader::~ParcelReader() = default;
157
ReadBinder() const158 BinderStatusOr<BinderRef> ParcelReader::ReadBinder() const {
159 WITH_BINDER_API(api) {
160 AIBinder* binder;
161 const auto status = api.AParcel_readStrongBinder(parcel_.get(), &binder);
162 if (status != STATUS_OK) {
163 return unexpected(status);
164 }
165 return BinderRef(binder);
166 }
167 return unexpected(STATUS_UNEXPECTED_NULL);
168 }
169
ReadInt32() const170 BinderStatusOr<int32_t> ParcelReader::ReadInt32() const {
171 WITH_BINDER_API(api) {
172 int32_t value;
173 const auto status = api.AParcel_readInt32(parcel_.get(), &value);
174 if (status != STATUS_OK) {
175 return unexpected(status);
176 }
177 return ok(value);
178 }
179 return unexpected(STATUS_UNEXPECTED_NULL);
180 }
181
ReadUint32() const182 BinderStatusOr<uint32_t> ParcelReader::ReadUint32() const {
183 WITH_BINDER_API(api) {
184 uint32_t value;
185 const auto status = api.AParcel_readUint32(parcel_.get(), &value);
186 if (status != STATUS_OK) {
187 return unexpected(status);
188 }
189 return ok(value);
190 }
191 return unexpected(STATUS_UNEXPECTED_NULL);
192 }
193
ReadUint64() const194 BinderStatusOr<uint64_t> ParcelReader::ReadUint64() const {
195 WITH_BINDER_API(api) {
196 uint64_t value;
197 const auto status = api.AParcel_readUint64(parcel_.get(), &value);
198 if (status != STATUS_OK) {
199 return unexpected(status);
200 }
201 return ok(value);
202 }
203 return unexpected(STATUS_UNEXPECTED_NULL);
204 }
205
ReadByteArrayImpl(AParcel_byteArrayAllocator allocator,void * context) const206 BinderStatusOr<void> ParcelReader::ReadByteArrayImpl(
207 AParcel_byteArrayAllocator allocator,
208 void* context) const {
209 WITH_BINDER_API(api) {
210 const auto status =
211 api.AParcel_readByteArray(parcel_.get(), context, allocator);
212 if (status != STATUS_OK) {
213 return unexpected(status);
214 }
215 return ok();
216 }
217 return unexpected(STATUS_UNEXPECTED_NULL);
218 }
219
ReadFileDescriptor() const220 BinderStatusOr<ScopedFD> ParcelReader::ReadFileDescriptor() const {
221 WITH_BINDER_API(api) {
222 int fd;
223 const auto status =
224 api.AParcel_readParcelFileDescriptor(parcel_.get(), &fd);
225 if (status != STATUS_OK) {
226 return unexpected(status);
227 }
228 return ScopedFD(fd);
229 }
230 return unexpected(STATUS_UNEXPECTED_NULL);
231 }
232
ParcelWriter(AParcel * parcel)233 ParcelWriter::ParcelWriter(AParcel* parcel) : parcel_(parcel) {}
234
ParcelWriter(Parcel & parcel)235 ParcelWriter::ParcelWriter(Parcel& parcel) : parcel_(parcel.get()) {}
236
237 ParcelWriter::ParcelWriter(const ParcelWriter&) = default;
238
239 ParcelWriter& ParcelWriter::operator=(const ParcelWriter&) = default;
240
241 ParcelWriter::~ParcelWriter() = default;
242
WriteBinder(BinderRef binder) const243 BinderStatusOr<void> ParcelWriter::WriteBinder(BinderRef binder) const {
244 binder_status_t status = STATUS_UNEXPECTED_NULL;
245 WITH_BINDER_API(api) {
246 status = api.AParcel_writeStrongBinder(parcel_.get(), binder.get());
247 if (status == STATUS_OK) {
248 return ok();
249 }
250 }
251 return unexpected(status);
252 }
253
WriteInt32(int32_t value) const254 BinderStatusOr<void> ParcelWriter::WriteInt32(int32_t value) const {
255 binder_status_t status = STATUS_UNEXPECTED_NULL;
256 WITH_BINDER_API(api) {
257 status = api.AParcel_writeInt32(parcel_.get(), value);
258 if (status == STATUS_OK) {
259 return ok();
260 }
261 }
262 return unexpected(status);
263 }
264
WriteUint32(uint32_t value) const265 BinderStatusOr<void> ParcelWriter::WriteUint32(uint32_t value) const {
266 binder_status_t status = STATUS_UNEXPECTED_NULL;
267 WITH_BINDER_API(api) {
268 status = api.AParcel_writeUint32(parcel_.get(), value);
269 if (status == STATUS_OK) {
270 return ok();
271 }
272 }
273 return unexpected(status);
274 }
275
WriteUint64(uint64_t value) const276 BinderStatusOr<void> ParcelWriter::WriteUint64(uint64_t value) const {
277 binder_status_t status = STATUS_UNEXPECTED_NULL;
278 WITH_BINDER_API(api) {
279 status = api.AParcel_writeUint64(parcel_.get(), value);
280 if (status == STATUS_OK) {
281 return ok();
282 }
283 }
284 return unexpected(status);
285 }
286
WriteByteArray(span<const uint8_t> bytes) const287 BinderStatusOr<void> ParcelWriter::WriteByteArray(
288 span<const uint8_t> bytes) const {
289 binder_status_t status = STATUS_UNEXPECTED_NULL;
290 WITH_BINDER_API(api) {
291 status = api.AParcel_writeByteArray(
292 parcel_.get(), reinterpret_cast<const int8_t*>(bytes.data()),
293 checked_cast<int32_t>(bytes.size()));
294 if (status == STATUS_OK) {
295 return ok();
296 }
297 }
298 return unexpected(status);
299 }
300
WriteFileDescriptor(ScopedFD file) const301 BinderStatusOr<void> ParcelWriter::WriteFileDescriptor(ScopedFD file) const {
302 binder_status_t status = STATUS_UNEXPECTED_NULL;
303 WITH_BINDER_API(api) {
304 status = api.AParcel_writeParcelFileDescriptor(parcel_.get(), file.get());
305 if (status == STATUS_OK) {
306 return ok();
307 }
308 }
309 return unexpected(status);
310 }
311
312 Parcel::Parcel() = default;
313
Parcel(AParcel * parcel)314 Parcel::Parcel(AParcel* parcel) : parcel_(parcel) {}
315
Parcel(Parcel && other)316 Parcel::Parcel(Parcel&& other) : parcel_(other.release()) {}
317
operator =(Parcel && other)318 Parcel& Parcel::operator=(Parcel&& other) {
319 reset();
320 parcel_ = other.release();
321 return *this;
322 }
323
~Parcel()324 Parcel::~Parcel() {
325 reset();
326 }
327
reset()328 void Parcel::reset() {
329 WITH_BINDER_API(api) {
330 if (AParcel* parcel = release()) {
331 api.AParcel_delete(parcel);
332 }
333 }
334 }
335
336 BinderRef::BinderRef() = default;
337
BinderRef(AIBinder * binder)338 BinderRef::BinderRef(AIBinder* binder) : binder_(binder) {}
339
BinderRef(const BinderRef & other)340 BinderRef::BinderRef(const BinderRef& other) : binder_(other.binder_) {
341 if (binder_) {
342 WITH_BINDER_API(api) {
343 api.AIBinder_incStrong(binder_);
344 }
345 }
346 }
347
operator =(const BinderRef & other)348 BinderRef& BinderRef::operator=(const BinderRef& other) {
349 reset();
350 binder_ = other.binder_;
351 if (binder_) {
352 WITH_BINDER_API(api) {
353 api.AIBinder_incStrong(binder_);
354 }
355 }
356 return *this;
357 }
358
BinderRef(BinderRef && other)359 BinderRef::BinderRef(BinderRef&& other) : binder_(other.release()) {}
360
operator =(BinderRef && other)361 BinderRef& BinderRef::operator=(BinderRef&& other) {
362 reset();
363 binder_ = other.release();
364 return *this;
365 }
366
~BinderRef()367 BinderRef::~BinderRef() {
368 reset();
369 }
370
reset()371 void BinderRef::reset() {
372 if (AIBinder* binder = release()) {
373 WITH_BINDER_API(api) {
374 api.AIBinder_decStrong(binder);
375 }
376 }
377 }
378
ToJavaBinder(JNIEnv * env) const379 ScopedJavaLocalRef<jobject> BinderRef::ToJavaBinder(JNIEnv* env) const {
380 ScopedJavaLocalRef<jobject> object;
381 if (binder_) {
382 WITH_BINDER_API(api) {
383 object = ScopedJavaLocalRef<jobject>::Adopt(
384 env, api.AIBinder_toJavaBinder(env, binder_.get()));
385 }
386 }
387 return object;
388 }
389
FromJavaBinder(JNIEnv * env,jobject java_binder)390 BinderRef BinderRef::FromJavaBinder(JNIEnv* env, jobject java_binder) {
391 WITH_BINDER_API(api) {
392 if (AIBinder* binder = api.AIBinder_fromJavaBinder(env, java_binder)) {
393 return BinderRef(binder);
394 }
395 }
396 return BinderRef();
397 }
398
AssociateWithClass(AIBinder_Class * binder_class)399 bool BinderRef::AssociateWithClass(AIBinder_Class* binder_class) {
400 if (binder_) {
401 WITH_BINDER_API(api) {
402 return api.AIBinder_associateClass(binder_.get(), binder_class);
403 }
404 }
405 return false;
406 }
407
PrepareTransaction()408 BinderStatusOr<Parcel> BinderRef::PrepareTransaction() {
409 if (binder_) {
410 WITH_BINDER_API(api) {
411 AParcel* parcel;
412 const auto status =
413 api.AIBinder_prepareTransaction(binder_.get(), &parcel);
414 if (status != STATUS_OK) {
415 return unexpected(status);
416 }
417 return Parcel(parcel);
418 }
419 }
420 return unexpected(STATUS_UNEXPECTED_NULL);
421 }
422
TransactImpl(transaction_code_t code,Parcel parcel,binder_flags_t flags)423 BinderStatusOr<Parcel> BinderRef::TransactImpl(transaction_code_t code,
424 Parcel parcel,
425 binder_flags_t flags) {
426 if (binder_) {
427 WITH_BINDER_API(api) {
428 // NOTE: AIBinder_transact always takes ownership of the input parcel even
429 // in failure modes. Hence it's safe to release here unconditionally.
430 AParcel* in = parcel.release();
431 AParcel* out;
432 const auto status =
433 api.AIBinder_transact(binder_.get(), code, &in, &out, flags);
434 if (status != STATUS_OK) {
435 return unexpected(status);
436 }
437 return Parcel(out);
438 }
439 }
440 return unexpected(STATUS_UNEXPECTED_NULL);
441 }
442
443 namespace internal {
444
RegisterBinderClass(const char * name)445 AIBinder_Class* BinderClassBase::RegisterBinderClass(const char* name) {
446 WITH_BINDER_API(api) {
447 return api.AIBinder_Class_define(name, &SupportsBinderBase::OnIBinderCreate,
448 &SupportsBinderBase::OnIBinderDestroy,
449 &SupportsBinderBase::OnIBinderTransact);
450 }
451 return nullptr;
452 }
453
SupportsBinderBase(AIBinder_Class * binder_class)454 SupportsBinderBase::SupportsBinderBase(AIBinder_Class* binder_class)
455 : binder_class_(binder_class) {}
456
~SupportsBinderBase()457 SupportsBinderBase::~SupportsBinderBase() {
458 #if DCHECK_IS_ON()
459 // If we're being destroyed there must no longer be an IBinder for this
460 // object. And in that case, `weak_binder_` should have already been cleared
461 // by OnIBinderDestroy().
462 AutoLock lock(lock_);
463 DCHECK(!weak_binder_);
464 #endif
465 }
466
GetBinder()467 BinderRef SupportsBinderBase::GetBinder() {
468 WITH_BINDER_API(api) {
469 AutoLock lock(lock_);
470 if (weak_binder_) {
471 AIBinder* strong = api.AIBinder_Weak_promote(weak_binder_.get());
472 if (strong) {
473 return BinderRef(strong);
474 }
475
476 // Our weak IBinder is no longer valid.
477 api.AIBinder_Weak_delete(weak_binder_.get());
478 weak_binder_ = nullptr;
479 }
480
481 // We have no IBinder, so create a new one.
482 AIBinder* binder = api.AIBinder_new(binder_class_.get(), this);
483 CHECK(binder);
484 weak_binder_ = api.AIBinder_Weak_new(binder);
485 self_for_binder_ = this;
486 return BinderRef(binder);
487 }
488
489 return BinderRef();
490 }
491
OnBinderDestroyed()492 void SupportsBinderBase::OnBinderDestroyed() {}
493
OnBinderDestroyedBase()494 void SupportsBinderBase::OnBinderDestroyedBase() {
495 scoped_refptr<SupportsBinderBase> self_ref;
496 WITH_BINDER_API(api) {
497 AutoLock lock(lock_);
498 if (weak_binder_) {
499 api.AIBinder_Weak_delete(weak_binder_.get());
500 weak_binder_ = nullptr;
501 }
502 self_ref.swap(self_for_binder_);
503 }
504 OnBinderDestroyed();
505
506 // May delete `this`.
507 self_ref.reset();
508 }
509
OnIBinderCreate(void * self)510 void* SupportsBinderBase::OnIBinderCreate(void* self) {
511 return self;
512 }
513
OnIBinderDestroy(void * self)514 void SupportsBinderBase::OnIBinderDestroy(void* self) {
515 reinterpret_cast<SupportsBinderBase*>(self)->OnBinderDestroyedBase();
516 }
517
OnIBinderTransact(AIBinder * binder,transaction_code_t code,const AParcel * in,AParcel * out)518 binder_status_t SupportsBinderBase::OnIBinderTransact(AIBinder* binder,
519 transaction_code_t code,
520 const AParcel* in,
521 AParcel* out) {
522 WITH_BINDER_API(api) {
523 void* const user_data = api.AIBinder_getUserData(binder);
524 auto* const target = reinterpret_cast<SupportsBinderBase*>(user_data);
525
526 const auto result =
527 target->OnBinderTransaction(code, ParcelReader(in), ParcelWriter(out));
528 return result.has_value() ? STATUS_OK : result.error();
529 }
530
531 // If binder NDK is unsupported, nobody will be calling this method.
532 NOTREACHED();
533 }
534
535 } // namespace internal
536
IsNativeBinderAvailable()537 bool IsNativeBinderAvailable() {
538 return GetBinderApi();
539 }
540
SetBindersFromParent(std::vector<BinderRef> binders)541 void SetBindersFromParent(std::vector<BinderRef> binders) {
542 CHECK(!BindersFromParent());
543 BindersFromParent() =
544 std::make_unique<std::vector<BinderRef>>(std::move(binders));
545 }
546
TakeBinderFromParent(size_t index)547 BinderRef TakeBinderFromParent(size_t index) {
548 auto& binders = BindersFromParent();
549 CHECK(binders);
550 if (index >= binders->size()) {
551 return BinderRef();
552 }
553 return std::move(binders->at(index));
554 }
555
556 } // namespace base::android
557