Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8323e86 authored by mattgilbride's avatar mattgilbride
Browse files

Make getCallingUidOrThrow() not throw in clearCallingIdentity() blocks

The new method hasExplicitIdentity will track whether the caller is
within a Binder.clearCallingIdentity/restoreCallingIdentity block based
on packing this state information into the token returned by clearCallingIdentity.

Bug: b/252975769
Test: android.os.cts.BinderTest
Change-Id: I162db933f9e52cd6f9f46796bda11ad6216d3d66
parent 0b703be0
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -327,17 +327,29 @@ public class Binder implements IBinder {
    @CriticalNative
    public static final native boolean isDirectlyHandlingTransaction();

    /**
    * Returns {@code true} if the current thread has had its identity
    * set explicitly via {@link #clearCallingIdentity()}
    *
    * @hide
    */
    @CriticalNative
    private static native boolean hasExplicitIdentity();

    /**
     * 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.
     * executing an incoming transaction and the calling identity has not been
     * explicitly set with {@link #clearCallingIdentity()}
     */
    public static final int getCallingUidOrThrow() {
        if (!isDirectlyHandlingTransaction()) {
        if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
            throw new IllegalStateException(
                  "Thread is not in a binder transcation");
                  "Thread is not in a binder transaction, "
                  + "and the calling identity has not been "
                  + "explicitly set with clearCallingIdentity");
        }
        return getCallingUid();
    }
+6 −0
Original line number Diff line number Diff line
@@ -983,6 +983,10 @@ static void android_os_Binder_restoreCallingIdentity(jlong token)
    IPCThreadState::self()->restoreCallingIdentity(token);
}

static jboolean android_os_Binder_hasExplicitIdentity() {
    return IPCThreadState::self()->hasExplicitIdentity();
}

static void android_os_Binder_setThreadStrictModePolicy(jint policyMask)
{
    IPCThreadState::self()->setStrictModePolicy(policyMask);
@@ -1079,6 +1083,8 @@ static const JNINativeMethod gBinderMethods[] = {
    // @CriticalNative
    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
    // @CriticalNative
    { "hasExplicitIdentity", "()Z", (void*)android_os_Binder_hasExplicitIdentity },
    // @CriticalNative
    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
    // @CriticalNative
    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
+4 −6
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import androidx.test.filters.SmallTest;

import junit.framework.TestCase;

import static org.testng.Assert.assertThrows;

public class BinderTest extends TestCase {
    private static final int UID = 100;

@@ -45,12 +47,8 @@ public class BinderTest extends TestCase {
    }

    @SmallTest
    public void testGetCallingUidOrThrow() throws Exception {
        try {
            Binder.getCallingUidOrThrow();
            throw new AssertionError("IllegalStateException expected");
        } catch (IllegalStateException expected) {
        }
    public void testGetCallingUidOrThrow_throws() throws Exception {
        assertThrows(IllegalStateException.class, () -> Binder.getCallingUidOrThrow());
    }

    @SmallTest