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
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user