Merge changes I7315059b,If2dd13d8 am: 08b17a98a8 am: 6f585129c4

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2270567

Change-Id: I326c2ebfdd409db4ce0b0d589a0ae3e560b20d6e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Steven Moreland
2022-10-27 22:05:11 +00:00
committed by Automerger Merge Worker
4 changed files with 54 additions and 11 deletions

View File

@@ -1219,25 +1219,40 @@ public class Binder implements IBinder {
@UnsupportedAppUsage @UnsupportedAppUsage
private boolean execTransact(int code, long dataObj, long replyObj, private boolean execTransact(int code, long dataObj, long replyObj,
int flags) { int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// At that point, the parcel request headers haven't been parsed so we do not know what // At that point, the parcel request headers haven't been parsed so we do not know what
// {@link WorkSource} the caller has set. Use calling UID as the default. // {@link WorkSource} the caller has set. Use calling UID as the default.
final int callingUid = Binder.getCallingUid(); //
final long origWorkSource = ThreadLocalWorkSource.setUid(callingUid); // TODO: this is wrong - we should attribute along the entire call route
// also this attribution logic should move to native code - it only works
// for Java now
//
// This attribution support is not generic and therefore not support in RPC mode
final int callingUid = data.isForRpc() ? -1 : Binder.getCallingUid();
final long origWorkSource = callingUid == -1
? -1 : ThreadLocalWorkSource.setUid(callingUid);
try { try {
return execTransactInternal(code, dataObj, replyObj, flags, callingUid); return execTransactInternal(code, data, reply, flags, callingUid);
} finally { } finally {
reply.recycle();
data.recycle();
if (callingUid != -1) {
ThreadLocalWorkSource.restore(origWorkSource); ThreadLocalWorkSource.restore(origWorkSource);
} }
} }
}
private boolean execTransactInternal(int code, long dataObj, long replyObj, int flags, private boolean execTransactInternal(int code, Parcel data, Parcel reply, int flags,
int callingUid) { int callingUid) {
// Make sure the observer won't change while processing a transaction. // Make sure the observer won't change while processing a transaction.
final BinderInternal.Observer observer = sObserver; final BinderInternal.Observer observer = sObserver;
final CallSession callSession = final CallSession callSession =
observer != null ? observer.callStarted(this, code, UNSET_WORKSOURCE) : null; observer != null ? observer.callStarted(this, code, UNSET_WORKSOURCE) : null;
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// Theoretically, we should call transact, which will call onTransact, // Theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC, // but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly. // so we'll just call it directly.
@@ -1268,8 +1283,10 @@ public class Binder implements IBinder {
final boolean tracingEnabled = tagEnabled && transactionTraceName != null; final boolean tracingEnabled = tagEnabled && transactionTraceName != null;
try { try {
// TODO - this logic should not be in Java - it should be in native
// code in libbinder so that it works for all binder users.
final BinderCallHeavyHitterWatcher heavyHitterWatcher = sHeavyHitterWatcher; final BinderCallHeavyHitterWatcher heavyHitterWatcher = sHeavyHitterWatcher;
if (heavyHitterWatcher != null) { if (heavyHitterWatcher != null && callingUid != -1) {
// Notify the heavy hitter watcher, if it's enabled. // Notify the heavy hitter watcher, if it's enabled.
heavyHitterWatcher.onTransaction(callingUid, getClass(), code); heavyHitterWatcher.onTransaction(callingUid, getClass(), code);
} }
@@ -1277,7 +1294,10 @@ public class Binder implements IBinder {
Trace.traceBegin(Trace.TRACE_TAG_AIDL, transactionTraceName); Trace.traceBegin(Trace.TRACE_TAG_AIDL, transactionTraceName);
} }
if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0) { // TODO - this logic should not be in Java - it should be in native
// code in libbinder so that it works for all binder users. Further,
// this should not re-use flags.
if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0 && callingUid != -1) {
AppOpsManager.startNotedAppOpsCollection(callingUid); AppOpsManager.startNotedAppOpsCollection(callingUid);
try { try {
res = onTransact(code, data, reply, flags); res = onTransact(code, data, reply, flags);
@@ -1320,8 +1340,6 @@ public class Binder implements IBinder {
} }
checkParcel(this, code, reply, "Unreasonably large binder reply buffer"); checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
reply.recycle();
data.recycle();
} }
// Just in case -- we are done with the IPC, so there should be no more strict // Just in case -- we are done with the IPC, so there should be no more strict

View File

@@ -368,6 +368,8 @@ public final class Parcel {
@FastNative @FastNative
private static native void nativeMarkForBinder(long nativePtr, IBinder binder); private static native void nativeMarkForBinder(long nativePtr, IBinder binder);
@CriticalNative @CriticalNative
private static native boolean nativeIsForRpc(long nativePtr);
@CriticalNative
private static native int nativeDataSize(long nativePtr); private static native int nativeDataSize(long nativePtr);
@CriticalNative @CriticalNative
private static native int nativeDataAvail(long nativePtr); private static native int nativeDataAvail(long nativePtr);
@@ -645,6 +647,15 @@ public final class Parcel {
nativeMarkForBinder(mNativePtr, binder); nativeMarkForBinder(mNativePtr, binder);
} }
/**
* Whether this Parcel is written for an RPC transaction.
*
* @hide
*/
public final boolean isForRpc() {
return nativeIsForRpc(mNativePtr);
}
/** @hide */ /** @hide */
@ParcelFlags @ParcelFlags
@TestApi @TestApi

View File

@@ -116,6 +116,11 @@ static void android_os_Parcel_markForBinder(JNIEnv* env, jclass clazz, jlong nat
} }
} }
static jboolean android_os_Parcel_isForRpc(jlong nativePtr) {
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
return parcel ? parcel->isForRpc() : false;
}
static jint android_os_Parcel_dataSize(jlong nativePtr) static jint android_os_Parcel_dataSize(jlong nativePtr)
{ {
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
@@ -808,6 +813,8 @@ static const JNINativeMethod gParcelMethods[] = {
// @FastNative // @FastNative
{"nativeMarkForBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_markForBinder}, {"nativeMarkForBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_markForBinder},
// @CriticalNative // @CriticalNative
{"nativeIsForRpc", "(J)Z", (void*)android_os_Parcel_isForRpc},
// @CriticalNative
{"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize}, {"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize},
// @CriticalNative // @CriticalNative
{"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail}, {"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail},

View File

@@ -36,6 +36,13 @@ public class ParcelTest {
private static final String INTERFACE_TOKEN_1 = "IBinder interface token"; private static final String INTERFACE_TOKEN_1 = "IBinder interface token";
private static final String INTERFACE_TOKEN_2 = "Another IBinder interface token"; private static final String INTERFACE_TOKEN_2 = "Another IBinder interface token";
@Test
public void testIsForRpc() {
Parcel p = Parcel.obtain();
assertEquals(false, p.isForRpc());
p.recycle();
}
@Test @Test
public void testCallingWorkSourceUidAfterWrite() { public void testCallingWorkSourceUidAfterWrite() {
Parcel p = Parcel.obtain(); Parcel p = Parcel.obtain();