From a929cf01cfb8b6d138c8724d586a8b9de75c0fac Mon Sep 17 00:00:00 2001 From: Nikita Ioffe Date: Thu, 3 Jan 2019 13:35:22 +0000 Subject: [PATCH] Add Binder.getCallingUidOrThrow method Binder.getCallingUidOrThrow is a pure java method which uses Binder.isHandlingTransaction @CriticalNative method. Binder.isHandlingTransaction itself is not exposed a public API. Bug: 62253865 Fix: 62253865 Test: Added a testcase to BinderTest.java to verify ISE is thrown Change-Id: I93a1b6c24a4747b8b70c32d291b4706b6159a3d0 --- api/current.txt | 1 + core/java/android/os/Binder.java | 24 +++++++++++++++++++ core/jni/android_util_Binder.cpp | 7 ++++++ .../coretests/src/android/os/BinderTest.java | 9 +++++++ 4 files changed, 41 insertions(+) diff --git a/api/current.txt b/api/current.txt index faf7c24c83fee..6c66fcd1d2a5d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -33698,6 +33698,7 @@ package android.os { method public static final void flushPendingCommands(); method public static final int getCallingPid(); method public static final int getCallingUid(); + method public static final int getCallingUidOrThrow(); method public static final android.os.UserHandle getCallingUserHandle(); method public java.lang.String getInterfaceDescriptor(); method public boolean isBinderAlive(); diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 9939a3c8f36de..1ebb551df9618 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -272,6 +272,30 @@ public class Binder implements IBinder { @CriticalNative public static final native int getCallingUid(); + /** + * Returns {@code true} if the current thread is currently executing an + * incoming transaction. + * + * @hide + */ + @CriticalNative + public static final native boolean isHandlingTransaction(); + + /** + * Return the Linux uid assigned to the process that sent the transaction + * currently being processed. + * + * @throws IllegalStateException if the current thread is not currently + * executing an incoming transaction. + */ + public static final int getCallingUidOrThrow() { + if (!isHandlingTransaction()) { + throw new IllegalStateException( + "Thread is not in a binder transcation"); + } + return getCallingUid(); + } + /** * Return the UserHandle assigned to the process that sent you the * current transaction that is being processed. This is the user diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 3329e2047085f..f201ceb40ff48 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -875,6 +875,11 @@ static jint android_os_Binder_getCallingUid() return IPCThreadState::self()->getCallingUid(); } +static jboolean android_os_Binder_isHandlingTransaction() +{ + return IPCThreadState::self()->isServingCall(); +} + static jlong android_os_Binder_clearCallingIdentity() { return IPCThreadState::self()->clearCallingIdentity(); @@ -960,6 +965,8 @@ static const JNINativeMethod gBinderMethods[] = { // @CriticalNative { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, // @CriticalNative + { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction }, + // @CriticalNative { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, // @CriticalNative diff --git a/core/tests/coretests/src/android/os/BinderTest.java b/core/tests/coretests/src/android/os/BinderTest.java index 534c5cdec259a..6c9c3c111ff82 100644 --- a/core/tests/coretests/src/android/os/BinderTest.java +++ b/core/tests/coretests/src/android/os/BinderTest.java @@ -43,4 +43,13 @@ public class BinderTest extends TestCase { Binder.restoreCallingWorkSource(token); assertEquals(UID, Binder.getCallingWorkSourceUid()); } + + @SmallTest + public void testGetCallingUidOrThrow() throws Exception { + try { + Binder.getCallingUidOrThrow(); + throw new AssertionError("IllegalStateException expected"); + } catch (IllegalStateException expected) { + } + } }