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

Commit 874d8163 authored by sandeepbandaru's avatar sandeepbandaru
Browse files

Adding method to check if a Parcel has any Binders marshalled in it.

This is an extension to the existing `hasFileDescriptors` method, both of which are "Active Objects" of a sort and allow writes across processes.
This check would be useful to perform validations on Bundle entries or
any Parcelable type if it only contains non-active objects and can be
essentially treated read only without having to inspect the marshalled
parcel object.

Test: TODO
Bug: 316589195
API-Coverage-Bug: 323147058
Change-Id: I1fd8c8a27e3e7b90df8fefb0fe77bbad908db6b6
parent dc6f83dd
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -475,6 +475,10 @@ public final class Parcel {
    private static native boolean nativeHasFileDescriptors(long nativePtr);
    private static native boolean nativeHasFileDescriptorsInRange(
            long nativePtr, int offset, int length);

    private static native boolean nativeHasBinders(long nativePtr);
    private static native boolean nativeHasBindersInRange(
            long nativePtr, int offset, int length);
    @RavenwoodThrow
    private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName);
    @RavenwoodThrow
@@ -969,6 +973,34 @@ public final class Parcel {
        return false;
    }

    /**
     * Report whether the parcel contains any marshalled IBinder objects.
     *
     * @throws UnsupportedOperationException if binder kernel driver was disabled or if method was
     *                                       invoked in case of Binder RPC protocol.
     * @hide
     */
    public boolean hasBinders() {
        return nativeHasBinders(mNativePtr);
    }

    /**
     * Report whether the parcel contains any marshalled {@link IBinder} objects in the range
     * defined by {@code offset} and {@code length}.
     *
     * @param offset The offset from which the range starts. Should be between 0 and
     *               {@link #dataSize()}.
     * @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
     *               offset}.
     * @return whether there are binders in the range or not.
     * @throws IllegalArgumentException if the parameters are out of the permitted ranges.
     *
     * @hide
     */
    public boolean hasBinders(int offset, int length) {
        return nativeHasBindersInRange(mNativePtr, offset, length);
    }

    /**
     * Store or read an IBinder interface token in the parcel at the current
     * {@link #dataPosition}. This is used to validate that the marshalled
+34 −1
Original line number Diff line number Diff line
@@ -661,6 +661,35 @@ static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNa
    return;
}

static jboolean android_os_Parcel_hasBinders(JNIEnv* env, jclass clazz, jlong nativePtr) {
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        bool result;
        status_t err = parcel->hasBinders(&result);
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
            return JNI_FALSE;
        }
        return result ? JNI_TRUE : JNI_FALSE;
    }
    return JNI_FALSE;
}

static jboolean android_os_Parcel_hasBindersInRange(JNIEnv* env, jclass clazz, jlong nativePtr,
                                                    jint offset, jint length) {
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        bool result;
        status_t err = parcel->hasBindersInRange(offset, length, &result);
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
            return JNI_FALSE;
        }
        return result ? JNI_TRUE : JNI_FALSE;
    }
    return JNI_FALSE;
}

static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr)
{
    jboolean ret = JNI_FALSE;
@@ -806,7 +835,7 @@ static jboolean android_os_Parcel_replaceCallingWorkSourceUid(jlong nativePtr, j
}

// ----------------------------------------------------------------------------

// clang-format off
static const JNINativeMethod gParcelMethods[] = {
    // @CriticalNative
    {"nativeMarkSensitive",       "(J)V", (void*)android_os_Parcel_markSensitive},
@@ -886,6 +915,9 @@ static const JNINativeMethod gParcelMethods[] = {
    // @CriticalNative
    {"nativeHasFileDescriptors",  "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
    {"nativeHasFileDescriptorsInRange",  "(JII)Z", (void*)android_os_Parcel_hasFileDescriptorsInRange},

    {"nativeHasBinders",  "(J)Z", (void*)android_os_Parcel_hasBinders},
    {"nativeHasBindersInRange",  "(JII)Z", (void*)android_os_Parcel_hasBindersInRange},
    {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
    {"nativeEnforceInterface",    "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},

@@ -900,6 +932,7 @@ static const JNINativeMethod gParcelMethods[] = {
    // @CriticalNative
    {"nativeReplaceCallingWorkSourceUid", "(JI)Z", (void*)android_os_Parcel_replaceCallingWorkSourceUid},
};
// clang-format on

const char* const kParcelPathName = "android/os/Parcel";

+26 −0
Original line number Diff line number Diff line
@@ -347,4 +347,30 @@ public class ParcelTest {
        p.recycle();
        Binder.setIsDirectlyHandlingTransactionOverride(false);
    }

    @Test
    @IgnoreUnderRavenwood(blockedBy = Parcel.class)
    public void testHasBinders_AfterWritingBinderToParcel() {
        Binder binder = new Binder();
        Parcel pA = Parcel.obtain();
        int iA = pA.dataPosition();
        pA.writeInt(13);
        assertFalse(pA.hasBinders());
        pA.writeStrongBinder(binder);
        assertTrue(pA.hasBinders());
    }


    @Test
    @IgnoreUnderRavenwood(blockedBy = Parcel.class)
    public void testHasBindersInRange_AfterWritingBinderToParcel() {
        Binder binder = new Binder();
        Parcel pA = Parcel.obtain();
        pA.writeInt(13);

        int binderStartPos = pA.dataPosition();
        pA.writeStrongBinder(binder);
        int binderEndPos = pA.dataPosition();
        assertTrue(pA.hasBinders(binderStartPos, binderEndPos - binderStartPos));
    }
}
+12 −0
Original line number Diff line number Diff line
@@ -383,9 +383,21 @@ public class Parcel_host {
        // Assume false for now, because we don't support writing FDs yet.
        return false;
    }

    public static boolean nativeHasFileDescriptorsInRange(
            long nativePtr, int offset, int length) {
        // Assume false for now, because we don't support writing FDs yet.
        return false;
    }

    public static boolean nativeHasBinders(long nativePtr) {
        // Assume false for now, because we don't support adding binders.
        return false;
    }

    public static boolean nativeHasBindersInRange(
            long nativePtr, int offset, int length) {
        // Assume false for now, because we don't support writing FDs yet.
        return false;
    }
}