Parcel: markForBinder

Allow Parcel data to be dependent on the binder in question. This
exposes the API in Java which is previously only available in native.

There are two main usecases for this:
- provide an alternative route to implement features like markSensitive
  (which requires only 1 function call per class, rather than a
  function call and flag per transaction type)
- support RPC format transactions

Bug: 175814583
Test: atest android.os.ParcelTest, boot, manual
Change-Id: I134b6e23da83699195a8f075b9f50b6409ecff86
This commit is contained in:
Steven Moreland
2021-09-01 11:05:00 -07:00
parent 44233c693c
commit 580ab91411
2 changed files with 39 additions and 2 deletions

View File

@@ -282,6 +282,8 @@ public final class Parcel {
@CriticalNative
private static native void nativeMarkSensitive(long nativePtr);
@FastNative
private static native void nativeMarkForBinder(long nativePtr, IBinder binder);
@CriticalNative
private static native int nativeDataSize(long nativePtr);
@CriticalNative
@@ -498,16 +500,40 @@ public final class Parcel {
/**
* Parcel data should be zero'd before realloc'd or deleted.
*
* Note: currently this feature requires multiple things to work in concert:
* - markSensitive must be called on every relative Parcel
* - FLAG_CLEAR_BUF must be passed into the kernel
* This requires having code which does the right thing in every method and in every backend
* of AIDL. Rather than exposing this API, it should be replaced with a single API on
* IBinder objects which can be called once, and the information should be fed into the
* Parcel using markForBinder APIs. In terms of code size and number of API calls, this is
* much more extensible.
*
* @hide
*/
public final void markSensitive() {
nativeMarkSensitive(mNativePtr);
}
/**
* Associate this parcel with a binder object. This marks the parcel as being prepared for a
* transaction on this specific binder object. Based on this, the format of the wire binder
* protocol may change. This should be called before any data is written to the parcel. If this
* is called multiple times, this will only be marked for the last binder. For future
* compatibility, it is recommended to call this on all parcels which are being sent over
* binder.
*
* @hide
*/
public void markForBinder(@NonNull IBinder binder) {
nativeMarkForBinder(mNativePtr, binder);
}
/**
* Returns the total amount of data contained in the parcel.
*/
public final int dataSize() {
public int dataSize() {
return nativeDataSize(mNativePtr);
}

View File

@@ -98,6 +98,15 @@ static void android_os_Parcel_markSensitive(jlong nativePtr)
}
}
static void android_os_Parcel_markForBinder(JNIEnv* env, jclass clazz, jlong nativePtr,
jobject binder)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel) {
parcel->markForBinder(ibinderForJavaObject(env, binder));
}
}
static jint android_os_Parcel_dataSize(jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
@@ -766,7 +775,9 @@ static jboolean android_os_Parcel_replaceCallingWorkSourceUid(jlong nativePtr, j
static const JNINativeMethod gParcelMethods[] = {
// @CriticalNative
{"nativeMarkSensitive", "(J)V", (void*)android_os_Parcel_markSensitive},
{"nativeMarkSensitive", "(J)V", (void*)android_os_Parcel_markSensitive},
// @FastNative
{"nativeMarkForBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_markForBinder},
// @CriticalNative
{"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize},
// @CriticalNative