1 /*
2 * Copyright (C) 2006 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 #define LOG_TAG "JavaBinder"
18 //#define LOG_NDEBUG 0
19
20 #include "android_util_Binder.h"
21
22 #include <android-base/stringprintf.h>
23 #include <binder/BpBinder.h>
24 #include <binder/IInterface.h>
25 #include <binder/IPCThreadState.h>
26 #include <binder/IServiceManager.h>
27 #include <binder/Parcel.h>
28 #include <binder/ProcessState.h>
29 #include <binder/Stability.h>
30 #include <binderthreadstate/CallerUtils.h>
31 #include <cutils/atomic.h>
32 #include <fcntl.h>
33 #include <inttypes.h>
34 #include <log/log.h>
35 #include <nativehelper/JNIHelp.h>
36 #include <nativehelper/ScopedLocalRef.h>
37 #include <nativehelper/ScopedUtfChars.h>
38 #include <stdio.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #include <utils/KeyedVector.h>
43 #include <utils/List.h>
44 #include <utils/Log.h>
45 #include <utils/String8.h>
46 #include <utils/SystemClock.h>
47 #include <utils/threads.h>
48
49 #include <atomic>
50 #include <mutex>
51 #include <string>
52
53 #include "android_os_Parcel.h"
54 #include "core_jni_helpers.h"
55
56 //#undef ALOGV
57 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
58
59 #define DEBUG_DEATH 0
60 #if DEBUG_DEATH
61 #define LOGDEATH ALOGD
62 #else
63 #define LOGDEATH ALOGV
64 #endif
65
66 using namespace android;
67
68 // ----------------------------------------------------------------------------
69
70 static struct bindernative_offsets_t
71 {
72 // Class state.
73 jclass mClass;
74 jmethodID mExecTransact;
75 jmethodID mGetInterfaceDescriptor;
76 jmethodID mTransactionCallback;
77
78 // Object state.
79 jfieldID mObject;
80
81 } gBinderOffsets;
82
83 // ----------------------------------------------------------------------------
84
85 static struct binderinternal_offsets_t
86 {
87 // Class state.
88 jclass mClass;
89 jmethodID mForceGc;
90 jmethodID mProxyLimitCallback;
91 jmethodID mProxyWarningCallback;
92
93 } gBinderInternalOffsets;
94
95 static struct sparseintarray_offsets_t
96 {
97 jclass classObject;
98 jmethodID constructor;
99 jmethodID put;
100 } gSparseIntArrayOffsets;
101
102 // ----------------------------------------------------------------------------
103
104 static struct error_offsets_t
105 {
106 jclass mError;
107 jclass mOutOfMemory;
108 jclass mStackOverflow;
109 } gErrorOffsets;
110
111 // ----------------------------------------------------------------------------
112
113 static struct binderproxy_offsets_t
114 {
115 // Class state.
116 jclass mClass;
117 jmethodID mGetInstance;
118 jmethodID mSendDeathNotice;
119
120 // Object state.
121 jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
122 } gBinderProxyOffsets;
123
124 static struct class_offsets_t
125 {
126 jmethodID mGetName;
127 } gClassOffsets;
128
129 // ----------------------------------------------------------------------------
130
131 static struct log_offsets_t
132 {
133 // Class state.
134 jclass mClass;
135 jmethodID mLogE;
136 } gLogOffsets;
137
138 static struct parcel_file_descriptor_offsets_t
139 {
140 jclass mClass;
141 jmethodID mConstructor;
142 } gParcelFileDescriptorOffsets;
143
144 static struct strict_mode_callback_offsets_t
145 {
146 jclass mClass;
147 jmethodID mCallback;
148 } gStrictModeCallbackOffsets;
149
150 static struct thread_dispatch_offsets_t
151 {
152 // Class state.
153 jclass mClass;
154 jmethodID mDispatchUncaughtException;
155 jmethodID mCurrentThread;
156 } gThreadDispatchOffsets;
157
158 // ****************************************************************************
159 // ****************************************************************************
160 // ****************************************************************************
161
162 static constexpr uint32_t GC_INTERVAL = 1000;
163
164 // Number of GlobalRefs held by JavaBBinders.
165 static std::atomic<uint32_t> gNumLocalRefsCreated(0);
166 static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
167 // Number of GlobalRefs held by JavaDeathRecipients.
168 static std::atomic<uint32_t> gNumDeathRefsCreated(0);
169 static std::atomic<uint32_t> gNumDeathRefsDeleted(0);
170
171 // We collected after creating this many refs.
172 static std::atomic<uint32_t> gCollectedAtRefs(0);
173
174 // Garbage collect if we've allocated at least GC_INTERVAL refs since the last time.
175 // TODO: Consider removing this completely. We should no longer be generating GlobalRefs
176 // that are reclaimed as a result of GC action.
177 __attribute__((no_sanitize("unsigned-integer-overflow")))
gcIfManyNewRefs(JNIEnv * env)178 static void gcIfManyNewRefs(JNIEnv* env)
179 {
180 uint32_t totalRefs = gNumLocalRefsCreated.load(std::memory_order_relaxed)
181 + gNumDeathRefsCreated.load(std::memory_order_relaxed);
182 uint32_t collectedAtRefs = gCollectedAtRefs.load(memory_order_relaxed);
183 // A bound on the number of threads that can have incremented gNum...RefsCreated before the
184 // following check is executed. Effectively a bound on #threads. Almost any value will do.
185 static constexpr uint32_t MAX_RACING = 100000;
186
187 if (totalRefs - (collectedAtRefs + GC_INTERVAL) /* modular arithmetic! */ < MAX_RACING) {
188 // Recently passed next GC interval.
189 if (gCollectedAtRefs.compare_exchange_strong(collectedAtRefs,
190 collectedAtRefs + GC_INTERVAL, std::memory_order_relaxed)) {
191 ALOGV("Binder forcing GC at %u created refs", totalRefs);
192 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
193 gBinderInternalOffsets.mForceGc);
194 } // otherwise somebody else beat us to it.
195 } else {
196 ALOGV("Now have %d binder ops", totalRefs - collectedAtRefs);
197 }
198 }
199
jnienv_to_javavm(JNIEnv * env)200 static JavaVM* jnienv_to_javavm(JNIEnv* env)
201 {
202 JavaVM* vm;
203 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
204 }
205
javavm_to_jnienv(JavaVM * vm)206 static JNIEnv* javavm_to_jnienv(JavaVM* vm)
207 {
208 JNIEnv* env;
209 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
210 }
211
GetErrorTypeName(JNIEnv * env,jthrowable error)212 static const char* GetErrorTypeName(JNIEnv* env, jthrowable error) {
213 if (env->IsInstanceOf(error, gErrorOffsets.mOutOfMemory)) {
214 return "OutOfMemoryError";
215 }
216 if (env->IsInstanceOf(error, gErrorOffsets.mStackOverflow)) {
217 return "StackOverflowError";
218 }
219 return nullptr;
220 }
221
222 // Report a java.lang.Error (or subclass). This will terminate the runtime by
223 // calling FatalError with a message derived from the given error.
report_java_lang_error_fatal_error(JNIEnv * env,jthrowable error,const char * msg)224 static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
225 const char* msg)
226 {
227 // Report an error: reraise the exception and ask the runtime to abort.
228
229 // Try to get the exception string. Sometimes logcat isn't available,
230 // so try to add it to the abort message.
231 std::string exc_msg;
232 {
233 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
234 jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
235 "()Ljava/lang/String;");
236 ScopedLocalRef<jstring> jstr(
237 env,
238 reinterpret_cast<jstring>(
239 env->CallObjectMethod(error, method_id)));
240 ScopedLocalRef<jthrowable> new_error(env, nullptr);
241 bool got_jstr = false;
242 if (env->ExceptionCheck()) {
243 new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
244 env->ExceptionClear();
245 }
246 if (jstr.get() != nullptr) {
247 ScopedUtfChars jstr_utf(env, jstr.get());
248 if (jstr_utf.c_str() != nullptr) {
249 exc_msg = jstr_utf.c_str();
250 got_jstr = true;
251 } else {
252 new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
253 env->ExceptionClear();
254 }
255 }
256 if (!got_jstr) {
257 exc_msg = "(Unknown exception message)";
258 const char* orig_type = GetErrorTypeName(env, error);
259 if (orig_type != nullptr) {
260 exc_msg = base::StringPrintf("%s (Error was %s)", exc_msg.c_str(), orig_type);
261 }
262 const char* new_type =
263 new_error == nullptr ? nullptr : GetErrorTypeName(env, new_error.get());
264 if (new_type != nullptr) {
265 exc_msg = base::StringPrintf("%s (toString() error was %s)",
266 exc_msg.c_str(),
267 new_type);
268 }
269 }
270 }
271
272 env->Throw(error);
273 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
274 env->ExceptionDescribe();
275
276 std::string error_msg = base::StringPrintf(
277 "java.lang.Error thrown during binder transaction: %s",
278 exc_msg.c_str());
279 env->FatalError(error_msg.c_str());
280 }
281
282 // Report a java.lang.Error (or subclass). This will terminate the runtime, either by
283 // the uncaught exception handler, or explicitly by calling
284 // report_java_lang_error_fatal_error.
report_java_lang_error(JNIEnv * env,jthrowable error,const char * msg)285 static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
286 {
287 // Try to run the uncaught exception machinery.
288 jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
289 gThreadDispatchOffsets.mCurrentThread);
290 if (thread != nullptr) {
291 env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
292 error);
293 // Should not return here, unless more errors occured.
294 }
295 // Some error occurred that meant that either dispatchUncaughtException could not be
296 // called or that it had an error itself (as this should be unreachable under normal
297 // conditions). As the binder code cannot handle Errors, attempt to log the error and
298 // abort.
299 env->ExceptionClear();
300 report_java_lang_error_fatal_error(env, error, msg);
301 }
302
303 namespace android {
304
binder_report_exception(JNIEnv * env,jthrowable excep,const char * msg)305 void binder_report_exception(JNIEnv* env, jthrowable excep, const char* msg) {
306 env->ExceptionClear();
307
308 ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
309 ScopedLocalRef<jstring> msgstr(env);
310 if (tagstr != nullptr) {
311 msgstr.reset(env->NewStringUTF(msg));
312 }
313
314 if ((tagstr != nullptr) && (msgstr != nullptr)) {
315 env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
316 tagstr.get(), msgstr.get(), excep);
317 if (env->ExceptionCheck()) {
318 // Attempting to log the failure has failed.
319 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
320 env->ExceptionClear();
321 }
322 } else {
323 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
324 ALOGE("Unable to call Log.e()\n");
325 ALOGE("%s", msg);
326 }
327
328 if (env->IsInstanceOf(excep, gErrorOffsets.mError)) {
329 report_java_lang_error(env, excep, msg);
330 }
331 }
332
333 } // namespace android
334
335 class JavaBBinderHolder;
336
337 class JavaBBinder : public BBinder
338 {
339 public:
JavaBBinder(JNIEnv * env,jobject object)340 JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
341 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
342 {
343 ALOGV("Creating JavaBBinder %p\n", this);
344 gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
345 gcIfManyNewRefs(env);
346 }
347
checkSubclass(const void * subclassID) const348 bool checkSubclass(const void* subclassID) const
349 {
350 return subclassID == &gBinderOffsets;
351 }
352
object() const353 jobject object() const
354 {
355 return mObject;
356 }
357
358 protected:
~JavaBBinder()359 virtual ~JavaBBinder()
360 {
361 ALOGV("Destroying JavaBBinder %p\n", this);
362 gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
363 JNIEnv* env = javavm_to_jnienv(mVM);
364 env->DeleteGlobalRef(mObject);
365 }
366
getInterfaceDescriptor() const367 const String16& getInterfaceDescriptor() const override
368 {
369 call_once(mPopulateDescriptor, [this] {
370 JNIEnv* env = javavm_to_jnienv(mVM);
371
372 ALOGV("getInterfaceDescriptor() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
373
374 jstring descriptor = (jstring)env->CallObjectMethod(mObject, gBinderOffsets.mGetInterfaceDescriptor);
375
376 if (descriptor == nullptr) {
377 return;
378 }
379
380 static_assert(sizeof(jchar) == sizeof(char16_t), "");
381 const jchar* descriptorChars = env->GetStringChars(descriptor, nullptr);
382 const char16_t* rawDescriptor = reinterpret_cast<const char16_t*>(descriptorChars);
383 jsize rawDescriptorLen = env->GetStringLength(descriptor);
384 mDescriptor = String16(rawDescriptor, rawDescriptorLen);
385 env->ReleaseStringChars(descriptor, descriptorChars);
386 });
387
388 return mDescriptor;
389 }
390
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)391 status_t onTransact(
392 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
393 {
394 JNIEnv* env = javavm_to_jnienv(mVM);
395
396 LOG_ALWAYS_FATAL_IF(env == nullptr,
397 "Binder thread started or Java binder used, but env null. Attach JVM?");
398
399 ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
400
401 IPCThreadState* thread_state = IPCThreadState::self();
402 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
403
404 //printf("Transact from %p to Java code sending: ", this);
405 //data.print();
406 //printf("\n");
407 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
408 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
409
410 if (env->ExceptionCheck()) {
411 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
412
413 auto state = IPCThreadState::self();
414 String8 msg;
415 msg.appendFormat("*** Uncaught remote exception! Exceptions are not yet supported "
416 "across processes. Client PID %d UID %d.",
417 state->getCallingPid(), state->getCallingUid());
418 binder_report_exception(env, excep.get(), msg.c_str());
419 res = JNI_FALSE;
420 }
421
422 // Check if the strict mode state changed while processing the
423 // call. The Binder state will be restored by the underlying
424 // Binder system in IPCThreadState, however we need to take care
425 // of the parallel Java state as well.
426 if (thread_state->getStrictModePolicy() != strict_policy_before) {
427 set_dalvik_blockguard_policy(env, strict_policy_before);
428 }
429
430 if (env->ExceptionCheck()) {
431 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
432 binder_report_exception(env, excep.get(),
433 "*** Uncaught exception in onBinderStrictModePolicyChange");
434 // TODO: should turn this to fatal?
435 }
436
437 // Need to always call through the native implementation of
438 // SYSPROPS_TRANSACTION.
439 if (code == SYSPROPS_TRANSACTION) {
440 BBinder::onTransact(code, data, reply, flags);
441 }
442
443 //aout << "onTransact to Java code; result=" << res << endl
444 // << "Transact from " << this << " to Java code returning "
445 // << reply << ": " << *reply << endl;
446 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
447 }
448
dump(int fd,const Vector<String16> & args)449 status_t dump(int fd, const Vector<String16>& args) override
450 {
451 return 0;
452 }
453
454 private:
455 JavaVM* const mVM;
456 jobject const mObject; // GlobalRef to Java Binder
457
458 mutable std::once_flag mPopulateDescriptor;
459 mutable String16 mDescriptor;
460 };
461
462 // ----------------------------------------------------------------------------
463
464 class JavaBBinderHolder
465 {
466 public:
get(JNIEnv * env,jobject obj)467 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
468 {
469 AutoMutex _l(mLock);
470 sp<JavaBBinder> b = mBinder.promote();
471 if (b == NULL) {
472 b = new JavaBBinder(env, obj);
473 if (mVintf) {
474 ::android::internal::Stability::markVintf(b.get());
475 }
476 if (mExtension != nullptr) {
477 b.get()->setExtension(mExtension);
478 }
479 mBinder = b;
480 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
481 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
482 }
483
484 return b;
485 }
486
getExisting()487 sp<JavaBBinder> getExisting()
488 {
489 AutoMutex _l(mLock);
490 return mBinder.promote();
491 }
492
markVintf()493 void markVintf() {
494 AutoMutex _l(mLock);
495 mVintf = true;
496 }
497
forceDowngradeToSystemStability()498 void forceDowngradeToSystemStability() {
499 AutoMutex _l(mLock);
500 mVintf = false;
501 }
502
getExtension()503 sp<IBinder> getExtension() {
504 AutoMutex _l(mLock);
505 sp<JavaBBinder> b = mBinder.promote();
506 if (b != nullptr) {
507 return b.get()->getExtension();
508 }
509 return mExtension;
510 }
511
setExtension(const sp<IBinder> & extension)512 void setExtension(const sp<IBinder>& extension) {
513 AutoMutex _l(mLock);
514 mExtension = extension;
515 sp<JavaBBinder> b = mBinder.promote();
516 if (b != nullptr) {
517 b.get()->setExtension(mExtension);
518 }
519 }
520
521 private:
522 Mutex mLock;
523 wp<JavaBBinder> mBinder;
524
525 // in the future, we might condense this into int32_t stability, or if there
526 // is too much binder state here, we can think about making JavaBBinder an
527 // sp here (avoid recreating it)
528 bool mVintf = false;
529
530 sp<IBinder> mExtension;
531 };
532
533 // ----------------------------------------------------------------------------
534
535 // Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
536 // death recipient references passed in through JNI with the permanent corresponding
537 // JavaDeathRecipient objects.
538
539 class JavaDeathRecipient;
540
541 class DeathRecipientList : public RefBase {
542 List< sp<JavaDeathRecipient> > mList;
543 Mutex mLock;
544
545 public:
546 DeathRecipientList();
547 ~DeathRecipientList();
548
549 void add(const sp<JavaDeathRecipient>& recipient);
550 void remove(const sp<JavaDeathRecipient>& recipient);
551 sp<JavaDeathRecipient> find(jobject recipient);
552
553 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
554 };
555
556 // ----------------------------------------------------------------------------
557 #ifdef BINDER_DEATH_RECIPIENT_WEAK_FROM_JNI
558 #if __BIONIC__
559 #include <android/api-level.h>
target_sdk_is_at_least_vic()560 static bool target_sdk_is_at_least_vic() {
561 return android_get_application_target_sdk_version() >= __ANDROID_API_V__;
562 }
563 #else
target_sdk_is_at_least_vic()564 static constexpr bool target_sdk_is_at_least_vic() {
565 // If not built for Android (i.e. glibc host), follow the latest behavior as there's no compat
566 // requirement there.
567 return true;
568 }
569 #endif // __BIONIC__
570 #endif // BINDER_DEATH_RECIPIENT_WEAK_FROM_JNI
571
572 class JavaDeathRecipient : public IBinder::DeathRecipient
573 {
574 public:
JavaDeathRecipient(JNIEnv * env,jobject object,const sp<DeathRecipientList> & list)575 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
576 : mVM(jnienv_to_javavm(env)), mObject(NULL), mObjectWeak(NULL), mList(list) {
577 // b/298374304: For apps targeting Android V or beyond, we no longer hold the global JNI ref
578 // to the death recipient objects. This is to prevent the memory leak which can happen when
579 // the death recipient object internally has a strong reference to the proxy object. Under
580 // the old behavior, you were unable to kill the binder service by dropping all references
581 // to the proxy object - because it is still strong referenced from JNI (here). The only way
582 // to cut the strong reference was to call unlinkDeath(), but it was easy to forget.
583 //
584 // Now, the strong reference to the death recipient is held in the Java-side proxy object.
585 // See BinderProxy.mDeathRecipients. From JNI, only the weak reference is kept. An
586 // implication of this is that you may not receive binderDied() if you drop all references
587 // to the proxy object before the service dies. This should be okay for most cases because
588 // you normally are not interested in the death of a binder service which you don't have any
589 // reference to. If however you want to get binderDied() regardless of the proxy object's
590 // lifecycle, keep a strong reference to the death recipient object by yourself.
591 #ifdef BINDER_DEATH_RECIPIENT_WEAK_FROM_JNI
592 if (target_sdk_is_at_least_vic()) {
593 mObjectWeak = env->NewWeakGlobalRef(object);
594 } else
595 #endif
596 {
597 mObject = env->NewGlobalRef(object);
598 }
599 // These objects manage their own lifetimes so are responsible for final bookkeeping.
600 // The list holds a strong reference to this object.
601 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
602 list->add(this);
603
604 gNumDeathRefsCreated.fetch_add(1, std::memory_order_relaxed);
605 gcIfManyNewRefs(env);
606 }
607
binderDied(const wp<IBinder> & who)608 void binderDied(const wp<IBinder>& who)
609 {
610 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
611 if (mObject == NULL && mObjectWeak == NULL) {
612 return;
613 }
614 JNIEnv* env = javavm_to_jnienv(mVM);
615 ScopedLocalRef<jobject> jBinderProxy(env, javaObjectForIBinder(env, who.promote()));
616
617 // Hold a local reference to the recipient. This may fail if the recipient is weakly
618 // referenced, in which case we can't deliver the death notice.
619 ScopedLocalRef<jobject> jRecipient(env,
620 env->NewLocalRef(mObject != NULL ? mObject
621 : mObjectWeak));
622 if (jRecipient.get() == NULL) {
623 ALOGW("Binder died, but death recipient is already garbage collected. If your target "
624 "sdk level is at or above 35, this can happen when you dropped all references to "
625 "the binder service before it died. If you want to get a death notice for a "
626 "binder service which you have no reference to, keep a strong reference to the "
627 "death recipient by yourself.");
628 return;
629 }
630
631 if (mFired) {
632 ALOGW("Received multiple death notices for the same binder object. Binder driver bug?");
633 return;
634 }
635 mFired = true;
636
637 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mSendDeathNotice,
638 jRecipient.get(), jBinderProxy.get());
639 if (env->ExceptionCheck()) {
640 jthrowable excep = env->ExceptionOccurred();
641 binder_report_exception(env, excep,
642 "*** Uncaught exception returned from death notification!");
643 }
644
645 // Demote from strong ref (if exists) to weak after binderDied() has been delivered, to
646 // allow the DeathRecipient and BinderProxy to be GC'd if no longer needed. Do this in sync
647 // with our containing DeathRecipientList so that we can't delete the global ref on mObject
648 // while the list is being iterated.
649 if (mObject != NULL) {
650 sp<DeathRecipientList> list = mList.promote();
651 if (list != NULL) {
652 AutoMutex _l(list->lock());
653
654 mObjectWeak = env->NewWeakGlobalRef(mObject);
655 env->DeleteGlobalRef(mObject);
656 mObject = NULL;
657 }
658 }
659 }
660
clearReference()661 void clearReference()
662 {
663 sp<DeathRecipientList> list = mList.promote();
664 if (list != NULL) {
665 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
666 list->remove(this);
667 } else {
668 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
669 }
670 }
671
matches(jobject obj)672 bool matches(jobject obj) {
673 bool result;
674 JNIEnv* env = javavm_to_jnienv(mVM);
675
676 if (mObject != NULL) {
677 result = env->IsSameObject(obj, mObject);
678 } else {
679 ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
680 result = env->IsSameObject(obj, me.get());
681 }
682 return result;
683 }
684
warnIfStillLive()685 void warnIfStillLive() {
686 if (mObject != NULL) {
687 // Okay, something is wrong -- we have a hard reference to a live death
688 // recipient on the VM side, but the list is being torn down.
689 JNIEnv* env = javavm_to_jnienv(mVM);
690 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
691 ScopedLocalRef<jstring> nameRef(env,
692 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
693 ScopedUtfChars nameUtf(env, nameRef.get());
694 if (nameUtf.c_str() != NULL) {
695 ALOGW("BinderProxy is being destroyed but the application did not call "
696 "unlinkToDeath to unlink all of its death recipients beforehand. "
697 "Releasing leaked death recipient: %s", nameUtf.c_str());
698 } else {
699 ALOGW("BinderProxy being destroyed; unable to get DR object name");
700 env->ExceptionClear();
701 }
702 }
703 }
704
705 protected:
~JavaDeathRecipient()706 virtual ~JavaDeathRecipient()
707 {
708 //ALOGI("Removing death ref: recipient=%p\n", mObject);
709 gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
710 JNIEnv* env = javavm_to_jnienv(mVM);
711 if (mObject != NULL) {
712 env->DeleteGlobalRef(mObject);
713 } else {
714 env->DeleteWeakGlobalRef(mObjectWeak);
715 }
716 }
717
718 private:
719 JavaVM* const mVM;
720
721 // If target sdk version < 35, the Java-side DeathRecipient is strongly referenced from mObject
722 // upon linkToDeath() and then after binderDied() is called, the strong reference is demoted to
723 // a weak reference (mObjectWeak).
724 // If target sdk version >= 35, the strong reference is never made here (i.e. mObject == NULL
725 // always). Instead, the strong reference to the Java-side DeathRecipient is made in
726 // BinderProxy.mDeathRecipients. In the native world, only the weak reference is kept.
727 jobject mObject;
728 jweak mObjectWeak;
729 wp<DeathRecipientList> mList;
730
731 // Whether binderDied was called or not.
732 bool mFired = false;
733 };
734
735 // ----------------------------------------------------------------------------
736
DeathRecipientList()737 DeathRecipientList::DeathRecipientList() {
738 LOGDEATH("New DRL @ %p", this);
739 }
740
~DeathRecipientList()741 DeathRecipientList::~DeathRecipientList() {
742 LOGDEATH("Destroy DRL @ %p", this);
743 AutoMutex _l(mLock);
744
745 // Should never happen -- the JavaDeathRecipient objects that have added themselves
746 // to the list are holding references on the list object. Only when they are torn
747 // down can the list header be destroyed.
748 if (mList.size() > 0) {
749 List< sp<JavaDeathRecipient> >::iterator iter;
750 for (iter = mList.begin(); iter != mList.end(); iter++) {
751 (*iter)->warnIfStillLive();
752 }
753 }
754 }
755
add(const sp<JavaDeathRecipient> & recipient)756 void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
757 AutoMutex _l(mLock);
758
759 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
760 mList.push_back(recipient);
761 }
762
remove(const sp<JavaDeathRecipient> & recipient)763 void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
764 AutoMutex _l(mLock);
765
766 List< sp<JavaDeathRecipient> >::iterator iter;
767 for (iter = mList.begin(); iter != mList.end(); iter++) {
768 if (*iter == recipient) {
769 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
770 mList.erase(iter);
771 return;
772 }
773 }
774 }
775
find(jobject recipient)776 sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
777 AutoMutex _l(mLock);
778
779 List< sp<JavaDeathRecipient> >::iterator iter;
780 for (iter = mList.begin(); iter != mList.end(); iter++) {
781 if ((*iter)->matches(recipient)) {
782 return *iter;
783 }
784 }
785 return NULL;
786 }
787
lock()788 Mutex& DeathRecipientList::lock() {
789 return mLock;
790 }
791
792 // ----------------------------------------------------------------------------
793
794 namespace android {
795
796 // We aggregate native pointer fields for BinderProxy in a single object to allow
797 // management with a single NativeAllocationRegistry, and to reduce the number of JNI
798 // Java field accesses. This costs us some extra indirections here.
799 struct BinderProxyNativeData {
800 // Both fields are constant and not null once javaObjectForIBinder returns this as
801 // part of a BinderProxy.
802
803 // The native IBinder proxied by this BinderProxy.
804 sp<IBinder> mObject;
805
806 // Death recipients for mObject. Reference counted only because DeathRecipients
807 // hold a weak reference that can be temporarily promoted.
808 sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
809 };
810
getBPNativeData(JNIEnv * env,jobject obj)811 BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
812 return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
813 }
814
815 // If the argument is a JavaBBinder, return the Java object that was used to create it.
816 // Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
817 // same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
javaObjectForIBinder(JNIEnv * env,const sp<IBinder> & val)818 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
819 {
820 // N.B. This function is called from a @FastNative JNI method, so don't take locks around
821 // calls to Java code or block the calling thread for a long time for any reason.
822
823 if (val == NULL) return NULL;
824
825 if (val->checkSubclass(&gBinderOffsets)) {
826 // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
827 jobject object = static_cast<JavaBBinder*>(val.get())->object();
828 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
829 return object;
830 }
831
832 BinderProxyNativeData* nativeData = new BinderProxyNativeData();
833 nativeData->mOrgue = new DeathRecipientList;
834 nativeData->mObject = val;
835
836 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
837 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
838 if (env->ExceptionCheck()) {
839 // In the exception case, getInstance still took ownership of nativeData.
840 return NULL;
841 }
842 BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
843 if (actualNativeData != nativeData) {
844 delete nativeData;
845 }
846
847 return object;
848 }
849
ibinderForJavaObject(JNIEnv * env,jobject obj)850 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
851 {
852 if (obj == NULL) return NULL;
853
854 // Instance of Binder?
855 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
856 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
857 env->GetLongField(obj, gBinderOffsets.mObject);
858
859 if (jbh == nullptr) {
860 ALOGE("JavaBBinderHolder null on binder");
861 return nullptr;
862 }
863
864 return jbh->get(env, obj);
865 }
866
867 // Instance of BinderProxy?
868 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
869 return getBPNativeData(env, obj)->mObject;
870 }
871
872 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
873 return NULL;
874 }
875
newParcelFileDescriptor(JNIEnv * env,jobject fileDesc)876 jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
877 {
878 return env->NewObject(
879 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
880 }
881
set_dalvik_blockguard_policy(JNIEnv * env,jint strict_policy)882 void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
883 {
884 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
885 // to sync our state back to it. See the comments in StrictMode.java.
886 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
887 gStrictModeCallbackOffsets.mCallback,
888 strict_policy);
889 }
890
signalExceptionForError(JNIEnv * env,jobject obj,status_t err,bool canThrowRemoteException,int parcelSize)891 void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
892 bool canThrowRemoteException, int parcelSize)
893 {
894 switch (err) {
895 case UNKNOWN_ERROR:
896 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
897 break;
898 case NO_MEMORY:
899 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
900 break;
901 case INVALID_OPERATION:
902 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
903 break;
904 case BAD_VALUE:
905 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
906 break;
907 case BAD_INDEX:
908 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
909 break;
910 case BAD_TYPE:
911 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
912 break;
913 case NAME_NOT_FOUND:
914 jniThrowException(env, "java/util/NoSuchElementException", NULL);
915 break;
916 case PERMISSION_DENIED:
917 jniThrowException(env, "java/lang/SecurityException", NULL);
918 break;
919 case NOT_ENOUGH_DATA:
920 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
921 break;
922 case NO_INIT:
923 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
924 break;
925 case ALREADY_EXISTS:
926 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
927 break;
928 case DEAD_OBJECT:
929 // DeadObjectException is a checked exception, only throw from certain methods.
930 jniThrowException(env, canThrowRemoteException
931 ? "android/os/DeadObjectException"
932 : "java/lang/RuntimeException", NULL);
933 break;
934 case UNKNOWN_TRANSACTION:
935 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
936 break;
937 case FAILED_TRANSACTION: {
938 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
939 const char* exceptionToThrow;
940 std::string msg;
941 // TransactionTooLargeException is a checked exception, only throw from certain methods.
942 // TODO(b/28321379): Transaction size is the most common cause for FAILED_TRANSACTION
943 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
944 // for other reasons also, such as if the transaction is malformed or
945 // refers to an FD that has been closed. We should change the driver
946 // to enable us to distinguish these cases in the future.
947 if (canThrowRemoteException && parcelSize > 200*1024) {
948 // bona fide large payload
949 exceptionToThrow = "android/os/TransactionTooLargeException";
950 msg = base::StringPrintf("data parcel size %d bytes", parcelSize);
951 } else {
952 // Heuristic: a payload smaller than this threshold "shouldn't" be too
953 // big, so it's probably some other, more subtle problem. In practice
954 // it seems to always mean that the remote process died while the binder
955 // transaction was already in flight.
956 exceptionToThrow = (canThrowRemoteException)
957 ? "android/os/DeadObjectException"
958 : "java/lang/RuntimeException";
959 msg = "Transaction failed on small parcel; remote process probably died, but "
960 "this could also be caused by running out of binder buffer space";
961 }
962 jniThrowException(env, exceptionToThrow, msg.c_str());
963 } break;
964 case FDS_NOT_ALLOWED:
965 jniThrowException(env, "java/lang/RuntimeException",
966 "Not allowed to write file descriptors here");
967 break;
968 case UNEXPECTED_NULL:
969 jniThrowNullPointerException(env, NULL);
970 break;
971 case -EBADF:
972 jniThrowException(env, "java/lang/RuntimeException",
973 "Bad file descriptor");
974 break;
975 case -ENFILE:
976 jniThrowException(env, "java/lang/RuntimeException",
977 "File table overflow");
978 break;
979 case -EMFILE:
980 jniThrowException(env, "java/lang/RuntimeException",
981 "Too many open files");
982 break;
983 case -EFBIG:
984 jniThrowException(env, "java/lang/RuntimeException",
985 "File too large");
986 break;
987 case -ENOSPC:
988 jniThrowException(env, "java/lang/RuntimeException",
989 "No space left on device");
990 break;
991 case -ESPIPE:
992 jniThrowException(env, "java/lang/RuntimeException",
993 "Illegal seek");
994 break;
995 case -EROFS:
996 jniThrowException(env, "java/lang/RuntimeException",
997 "Read-only file system");
998 break;
999 case -EMLINK:
1000 jniThrowException(env, "java/lang/RuntimeException",
1001 "Too many links");
1002 break;
1003 default:
1004 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
1005 String8 msg;
1006 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
1007 // RemoteException is a checked exception, only throw from certain methods.
1008 jniThrowException(env,
1009 canThrowRemoteException ? "android/os/RemoteException"
1010 : "java/lang/RuntimeException",
1011 msg.c_str());
1012 break;
1013 }
1014 }
1015
1016 }
1017
1018 // ----------------------------------------------------------------------------
1019
android_os_Binder_getCallingPid()1020 static jint android_os_Binder_getCallingPid()
1021 {
1022 return IPCThreadState::self()->getCallingPid();
1023 }
1024
android_os_Binder_getCallingUid()1025 static jint android_os_Binder_getCallingUid()
1026 {
1027 return IPCThreadState::self()->getCallingUid();
1028 }
1029
android_os_Binder_isDirectlyHandlingTransactionNative()1030 static jboolean android_os_Binder_isDirectlyHandlingTransactionNative() {
1031 return getCurrentServingCall() == BinderCallType::BINDER;
1032 }
1033
android_os_Binder_clearCallingIdentity()1034 static jlong android_os_Binder_clearCallingIdentity()
1035 {
1036 return IPCThreadState::self()->clearCallingIdentity();
1037 }
1038
android_os_Binder_restoreCallingIdentity(jlong token)1039 static void android_os_Binder_restoreCallingIdentity(jlong token)
1040 {
1041 IPCThreadState::self()->restoreCallingIdentity(token);
1042 }
1043
android_os_Binder_hasExplicitIdentity()1044 static jboolean android_os_Binder_hasExplicitIdentity() {
1045 return IPCThreadState::self()->hasExplicitIdentity();
1046 }
1047
android_os_Binder_setThreadStrictModePolicy(jint policyMask)1048 static void android_os_Binder_setThreadStrictModePolicy(jint policyMask)
1049 {
1050 IPCThreadState::self()->setStrictModePolicy(policyMask);
1051 }
1052
android_os_Binder_getThreadStrictModePolicy()1053 static jint android_os_Binder_getThreadStrictModePolicy()
1054 {
1055 return IPCThreadState::self()->getStrictModePolicy();
1056 }
1057
android_os_Binder_setCallingWorkSourceUid(jint workSource)1058 static jlong android_os_Binder_setCallingWorkSourceUid(jint workSource)
1059 {
1060 return IPCThreadState::self()->setCallingWorkSourceUid(workSource);
1061 }
1062
android_os_Binder_getCallingWorkSourceUid()1063 static jlong android_os_Binder_getCallingWorkSourceUid()
1064 {
1065 return IPCThreadState::self()->getCallingWorkSourceUid();
1066 }
1067
android_os_Binder_clearCallingWorkSource()1068 static jlong android_os_Binder_clearCallingWorkSource()
1069 {
1070 return IPCThreadState::self()->clearCallingWorkSource();
1071 }
1072
android_os_Binder_restoreCallingWorkSource(jlong token)1073 static void android_os_Binder_restoreCallingWorkSource(jlong token)
1074 {
1075 IPCThreadState::self()->restoreCallingWorkSource(token);
1076 }
1077
android_os_Binder_markVintfStability(JNIEnv * env,jobject clazz)1078 static void android_os_Binder_markVintfStability(JNIEnv* env, jobject clazz) {
1079 JavaBBinderHolder* jbh =
1080 (JavaBBinderHolder*) env->GetLongField(clazz, gBinderOffsets.mObject);
1081 jbh->markVintf();
1082 }
1083
android_os_Binder_forceDowngradeToSystemStability(JNIEnv * env,jobject clazz)1084 static void android_os_Binder_forceDowngradeToSystemStability(JNIEnv* env, jobject clazz) {
1085 JavaBBinderHolder* jbh =
1086 (JavaBBinderHolder*) env->GetLongField(clazz, gBinderOffsets.mObject);
1087 jbh->forceDowngradeToSystemStability();
1088 }
1089
android_os_Binder_flushPendingCommands(JNIEnv * env,jobject clazz)1090 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
1091 {
1092 IPCThreadState::self()->flushCommands();
1093 }
1094
android_os_Binder_getNativeBBinderHolder(JNIEnv * env,jobject clazz)1095 static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
1096 {
1097 JavaBBinderHolder* jbh = new JavaBBinderHolder();
1098 return (jlong) jbh;
1099 }
1100
Binder_destroy(void * rawJbh)1101 static void Binder_destroy(void* rawJbh)
1102 {
1103 JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
1104 ALOGV("Java Binder: deleting holder %p", jbh);
1105 delete jbh;
1106 }
1107
android_os_Binder_getNativeFinalizer(JNIEnv *,jclass)1108 JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
1109 return (jlong) Binder_destroy;
1110 }
1111
android_os_Binder_blockUntilThreadAvailable(JNIEnv * env,jobject clazz)1112 static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
1113 {
1114 return IPCThreadState::self()->blockUntilThreadAvailable();
1115 }
1116
android_os_Binder_getExtension(JNIEnv * env,jobject obj)1117 static jobject android_os_Binder_getExtension(JNIEnv* env, jobject obj) {
1118 JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
1119 return javaObjectForIBinder(env, jbh->getExtension());
1120 }
1121
android_os_Binder_setExtension(JNIEnv * env,jobject obj,jobject extensionObject)1122 static void android_os_Binder_setExtension(JNIEnv* env, jobject obj, jobject extensionObject) {
1123 JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
1124 sp<IBinder> extension = ibinderForJavaObject(env, extensionObject);
1125 jbh->setExtension(extension);
1126 }
1127
1128 // ----------------------------------------------------------------------------
1129
1130 // clang-format off
1131 static const JNINativeMethod gBinderMethods[] = {
1132 /* name, signature, funcPtr */
1133 // @CriticalNative
1134 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
1135 // @CriticalNative
1136 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
1137 // @CriticalNative
1138 { "isDirectlyHandlingTransactionNative", "()Z",
1139 (void*)android_os_Binder_isDirectlyHandlingTransactionNative },
1140 // @CriticalNative
1141 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
1142 // @CriticalNative
1143 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
1144 // @CriticalNative
1145 { "hasExplicitIdentity", "()Z", (void*)android_os_Binder_hasExplicitIdentity },
1146 // @CriticalNative
1147 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
1148 // @CriticalNative
1149 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
1150 // @CriticalNative
1151 { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
1152 // @CriticalNative
1153 { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
1154 // @CriticalNative
1155 { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
1156 { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
1157 { "markVintfStability", "()V", (void*)android_os_Binder_markVintfStability},
1158 { "forceDowngradeToSystemStability", "()V", (void*)android_os_Binder_forceDowngradeToSystemStability},
1159 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
1160 { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
1161 { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
1162 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
1163 { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension },
1164 { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
1165 };
1166 // clang-format on
1167
1168 const char* const kBinderPathName = "android/os/Binder";
1169
int_register_android_os_Binder(JNIEnv * env)1170 static int int_register_android_os_Binder(JNIEnv* env)
1171 {
1172 jclass clazz = FindClassOrDie(env, kBinderPathName);
1173
1174 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1175 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
1176 gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
1177 "()Ljava/lang/String;");
1178 gBinderOffsets.mTransactionCallback =
1179 GetStaticMethodIDOrDie(env, clazz, "transactionCallback", "(IIII)V");
1180 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
1181
1182 return RegisterMethodsOrDie(
1183 env, kBinderPathName,
1184 gBinderMethods, NELEM(gBinderMethods));
1185 }
1186
1187 // ****************************************************************************
1188 // ****************************************************************************
1189 // ****************************************************************************
1190
1191 namespace android {
1192
android_os_Debug_getLocalObjectCount(JNIEnv * env,jobject clazz)1193 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
1194 {
1195 return gNumLocalRefsCreated - gNumLocalRefsDeleted;
1196 }
1197
android_os_Debug_getProxyObjectCount(JNIEnv * env,jobject clazz)1198 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
1199 {
1200 return BpBinder::getBinderProxyCount();
1201 }
1202
android_os_Debug_getDeathObjectCount(JNIEnv * env,jobject clazz)1203 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
1204 {
1205 return gNumDeathRefsCreated - gNumDeathRefsDeleted;
1206 }
1207
1208 }
1209
1210 // ****************************************************************************
1211 // ****************************************************************************
1212 // ****************************************************************************
1213
android_os_BinderInternal_getContextObject(JNIEnv * env,jobject clazz)1214 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
1215 {
1216 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1217 return javaObjectForIBinder(env, b);
1218 }
1219
android_os_BinderInternal_joinThreadPool(JNIEnv * env,jobject clazz)1220 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
1221 {
1222 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1223 android::IPCThreadState::self()->joinThreadPool();
1224 }
1225
android_os_BinderInternal_disableBackgroundScheduling(JNIEnv * env,jobject clazz,jboolean disable)1226 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
1227 jobject clazz, jboolean disable)
1228 {
1229 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
1230 }
1231
android_os_BinderInternal_setMaxThreads(JNIEnv * env,jobject clazz,jint maxThreads)1232 static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
1233 jobject clazz, jint maxThreads)
1234 {
1235 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
1236 }
1237
android_os_BinderInternal_handleGc(JNIEnv * env,jobject clazz)1238 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
1239 {
1240 ALOGV("Gc has executed, updating Refs count at GC");
1241 gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
1242 }
1243
android_os_BinderInternal_proxyLimitCallback(int uid)1244 static void android_os_BinderInternal_proxyLimitCallback(int uid)
1245 {
1246 JNIEnv *env = AndroidRuntime::getJNIEnv();
1247 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1248 gBinderInternalOffsets.mProxyLimitCallback,
1249 uid);
1250
1251 if (env->ExceptionCheck()) {
1252 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1253 binder_report_exception(env, excep.get(),
1254 "*** Uncaught exception in binderProxyLimitCallbackFromNative");
1255 }
1256 }
1257
android_os_BinderInternal_proxyWarningCallback(int uid)1258 static void android_os_BinderInternal_proxyWarningCallback(int uid)
1259 {
1260 JNIEnv *env = AndroidRuntime::getJNIEnv();
1261 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1262 gBinderInternalOffsets.mProxyWarningCallback,
1263 uid);
1264
1265 if (env->ExceptionCheck()) {
1266 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1267 binder_report_exception(env, excep.get(),
1268 "*** Uncaught exception in binderProxyWarningCallbackFromNative");
1269 }
1270 }
1271
android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv * env,jobject clazz,jboolean enable)1272 static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
1273 jboolean enable)
1274 {
1275 BpBinder::setCountByUidEnabled((bool) enable);
1276 }
1277
android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv * env,jclass clazz)1278 static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1279 {
1280 Vector<uint32_t> uids, counts;
1281 BpBinder::getCountByUid(uids, counts);
1282 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1283 gSparseIntArrayOffsets.constructor);
1284 for (size_t i = 0; i < uids.size(); i++) {
1285 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1286 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1287 }
1288 return sparseIntArray;
1289 }
1290
android_os_BinderInternal_getBinderProxyCount(JNIEnv * env,jobject clazz,jint uid)1291 static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1292 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1293 }
1294
android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv * env,jobject clazz,jint high,jint low,jint warning)1295 static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1296 jint high, jint low,
1297 jint warning)
1298 {
1299 BpBinder::setBinderProxyCountWatermarks(high, low, warning);
1300 }
1301
1302 // ----------------------------------------------------------------------------
1303
1304 static const JNINativeMethod gBinderInternalMethods[] = {
1305 /* name, signature, funcPtr */
1306 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
1307 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
1308 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
1309 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
1310 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
1311 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
1312 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
1313 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
1314 { "nSetBinderProxyCountWatermarks", "(III)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
1315 };
1316
1317 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1318
int_register_android_os_BinderInternal(JNIEnv * env)1319 static int int_register_android_os_BinderInternal(JNIEnv* env)
1320 {
1321 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
1322
1323 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1324 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
1325 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1326 gBinderInternalOffsets.mProxyWarningCallback =
1327 GetStaticMethodIDOrDie(env, clazz, "binderProxyWarningCallbackFromNative", "(I)V");
1328
1329 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1330 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1331 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1332 "<init>", "()V");
1333 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1334 "(II)V");
1335
1336 BpBinder::setBinderProxyCountEventCallback(android_os_BinderInternal_proxyLimitCallback,
1337 android_os_BinderInternal_proxyWarningCallback);
1338
1339 return RegisterMethodsOrDie(
1340 env, kBinderInternalPathName,
1341 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1342 }
1343
1344 // ****************************************************************************
1345 // ****************************************************************************
1346 // ****************************************************************************
1347
android_os_BinderProxy_pingBinder(JNIEnv * env,jobject obj)1348 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1349 {
1350 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1351 if (target == NULL) {
1352 return JNI_FALSE;
1353 }
1354 status_t err = target->pingBinder();
1355 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1356 }
1357
android_os_BinderProxy_getInterfaceDescriptor(JNIEnv * env,jobject obj)1358 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1359 {
1360 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1361 if (target != NULL) {
1362 const String16& desc = target->getInterfaceDescriptor();
1363 return env->NewString(reinterpret_cast<const jchar*>(desc.c_str()), desc.size());
1364 }
1365 jniThrowException(env, "java/lang/RuntimeException",
1366 "No binder found for object");
1367 return NULL;
1368 }
1369
android_os_BinderProxy_isBinderAlive(JNIEnv * env,jobject obj)1370 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1371 {
1372 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1373 if (target == NULL) {
1374 return JNI_FALSE;
1375 }
1376 bool alive = target->isBinderAlive();
1377 return alive ? JNI_TRUE : JNI_FALSE;
1378 }
1379
android_os_BinderProxy_transact(JNIEnv * env,jobject obj,jint code,jobject dataObj,jobject replyObj,jint flags)1380 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1381 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1382 {
1383 if (dataObj == NULL) {
1384 jniThrowNullPointerException(env, NULL);
1385 return JNI_FALSE;
1386 }
1387
1388 Parcel* data = parcelForJavaObject(env, dataObj);
1389 if (data == NULL) {
1390 return JNI_FALSE;
1391 }
1392 Parcel* reply = parcelForJavaObject(env, replyObj);
1393 if (reply == NULL && replyObj != NULL) {
1394 return JNI_FALSE;
1395 }
1396
1397 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1398 if (target == NULL) {
1399 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1400 return JNI_FALSE;
1401 }
1402
1403 ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
1404 target, obj, code);
1405
1406 //printf("Transact from Java code to %p sending: ", target); data->print();
1407 status_t err = target->transact(code, *data, reply, flags);
1408 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1409
1410 if (err == NO_ERROR) {
1411 return JNI_TRUE;
1412 }
1413
1414 env->CallStaticVoidMethod(gBinderOffsets.mClass, gBinderOffsets.mTransactionCallback, getpid(),
1415 code, flags, err);
1416
1417 if (err == UNKNOWN_TRANSACTION) {
1418 return JNI_FALSE;
1419 }
1420
1421 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
1422 return JNI_FALSE;
1423 }
1424
android_os_BinderProxy_linkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1425 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
1426 jobject recipient, jint flags) // throws RemoteException
1427 {
1428 if (recipient == NULL) {
1429 jniThrowNullPointerException(env, NULL);
1430 return;
1431 }
1432
1433 BinderProxyNativeData *nd = getBPNativeData(env, obj);
1434 IBinder* target = nd->mObject.get();
1435
1436 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
1437
1438 if (!target->localBinder()) {
1439 DeathRecipientList* list = nd->mOrgue.get();
1440 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
1441 status_t err = target->linkToDeath(jdr, NULL, flags);
1442 if (err != NO_ERROR) {
1443 // Failure adding the death recipient, so clear its reference
1444 // now.
1445 jdr->clearReference();
1446 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1447 }
1448 }
1449 }
1450
android_os_BinderProxy_unlinkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1451 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1452 jobject recipient, jint flags)
1453 {
1454 jboolean res = JNI_FALSE;
1455 if (recipient == NULL) {
1456 jniThrowNullPointerException(env, NULL);
1457 return res;
1458 }
1459
1460 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1461 IBinder* target = nd->mObject.get();
1462 if (target == NULL) {
1463 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1464 return JNI_FALSE;
1465 }
1466
1467 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
1468
1469 if (!target->localBinder()) {
1470 status_t err = NAME_NOT_FOUND;
1471
1472 // If we find the matching recipient, proceed to unlink using that
1473 DeathRecipientList* list = nd->mOrgue.get();
1474 sp<JavaDeathRecipient> origJDR = list->find(recipient);
1475 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
1476 if (origJDR != NULL) {
1477 wp<IBinder::DeathRecipient> dr;
1478 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1479 if (err == NO_ERROR && dr != NULL) {
1480 sp<IBinder::DeathRecipient> sdr = dr.promote();
1481 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1482 if (jdr != NULL) {
1483 jdr->clearReference();
1484 }
1485 }
1486 }
1487
1488 if (err == NO_ERROR || err == DEAD_OBJECT) {
1489 res = JNI_TRUE;
1490 } else {
1491 jniThrowException(env, "java/util/NoSuchElementException",
1492 base::StringPrintf("Death link does not exist (%s)",
1493 statusToString(err).c_str())
1494 .c_str());
1495 }
1496 }
1497
1498 return res;
1499 }
1500
BinderProxy_destroy(void * rawNativeData)1501 static void BinderProxy_destroy(void* rawNativeData)
1502 {
1503 BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
1504 LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
1505 nativeData->mObject.get(), nativeData->mOrgue.get());
1506 delete nativeData;
1507 IPCThreadState::self()->flushCommands();
1508 }
1509
android_os_BinderProxy_getNativeFinalizer(JNIEnv *,jclass)1510 JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
1511 return (jlong) BinderProxy_destroy;
1512 }
1513
android_os_BinderProxy_getExtension(JNIEnv * env,jobject obj)1514 static jobject android_os_BinderProxy_getExtension(JNIEnv* env, jobject obj) {
1515 IBinder* binder = getBPNativeData(env, obj)->mObject.get();
1516 if (binder == nullptr) {
1517 jniThrowException(env, "java/lang/IllegalStateException", "Native IBinder is null");
1518 return nullptr;
1519 }
1520 sp<IBinder> extension;
1521 status_t err = binder->getExtension(&extension);
1522 if (err != OK) {
1523 signalExceptionForError(env, obj, err, true /* canThrowRemoteException */);
1524 return nullptr;
1525 }
1526 return javaObjectForIBinder(env, extension);
1527 }
1528
1529 // ----------------------------------------------------------------------------
1530
1531 // clang-format off
1532 static const JNINativeMethod gBinderProxyMethods[] = {
1533 /* name, signature, funcPtr */
1534 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1535 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1536 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
1537 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
1538 {"linkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1539 {"unlinkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1540 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
1541 {"getExtension", "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension},
1542 };
1543 // clang-format on
1544
1545 const char* const kBinderProxyPathName = "android/os/BinderProxy";
1546
int_register_android_os_BinderProxy(JNIEnv * env)1547 static int int_register_android_os_BinderProxy(JNIEnv* env)
1548 {
1549 gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
1550 gErrorOffsets.mOutOfMemory =
1551 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
1552 gErrorOffsets.mStackOverflow =
1553 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));
1554
1555 jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
1556 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1557 gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
1558 "(JJ)Landroid/os/BinderProxy;");
1559 gBinderProxyOffsets.mSendDeathNotice =
1560 GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1561 "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
1562 gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
1563
1564 clazz = FindClassOrDie(env, "java/lang/Class");
1565 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
1566
1567 return RegisterMethodsOrDie(
1568 env, kBinderProxyPathName,
1569 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1570 }
1571
1572 // ****************************************************************************
1573 // ****************************************************************************
1574 // ****************************************************************************
1575
register_android_os_Binder(JNIEnv * env)1576 int register_android_os_Binder(JNIEnv* env)
1577 {
1578 if (int_register_android_os_Binder(env) < 0)
1579 return -1;
1580 if (int_register_android_os_BinderInternal(env) < 0)
1581 return -1;
1582 if (int_register_android_os_BinderProxy(env) < 0)
1583 return -1;
1584
1585 jclass clazz = FindClassOrDie(env, "android/util/Log");
1586 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1587 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1588 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
1589
1590 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1591 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1592 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1593 "(Ljava/io/FileDescriptor;)V");
1594
1595 clazz = FindClassOrDie(env, "android/os/StrictMode");
1596 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1597 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1598 "onBinderStrictModePolicyChange", "(I)V");
1599
1600 clazz = FindClassOrDie(env, "java/lang/Thread");
1601 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1602 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1603 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1604 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1605 "()Ljava/lang/Thread;");
1606
1607 return 0;
1608 }
1609