• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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