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

Commit 0bb6108b authored by Steven Moreland's avatar Steven Moreland
Browse files

Assert Parcel not in pool when used (partial reland)

Parcel lifetime, according to its API contract, ends
when Parcel.recycle() is called. However, sometimes
people use it after this point, especially in exception
handling and other complex code. This causes what is
effectively a UAF issue, as the ownership of that Parcel
may be opened for another user in the same process.

In order to resolve this, whenever a Parcel is used
while it is in the pool, we consider this an error.

This is only added on readInt, since it is used on
every Parcel. Adding this to all 200+ Parcel methods
causes too much memory due to heavy inlining of these
methods.

Bug: 381155347
Test: boot
Change-Id: I77c54c66c54b73f0df6c350ee9cb66a16c253e43
parent 73a93318
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import com.android.internal.util.ArrayUtils;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
import dalvik.annotation.optimization.NeverInline;

import libcore.util.SneakyThrow;

@@ -628,6 +629,19 @@ public final class Parcel {
        }
    }

    @NeverInline
    private void errorUsedWhileRecycling() {
        String error = "Parcel used while recycled. "
                + Log.getStackTraceString(new Throwable())
                + " Original recycle call (if DEBUG_RECYCLE): ", mStack;
        Log.wtf(TAG, error);
        // TODO(b/381155347): harder error
    }

    private void assertNotRecycled() {
        if (mRecycled) errorUsedWhileRecycling();
    }

    /**
     * Set a {@link ReadWriteHelper}, which can be used to avoid having duplicate strings, for
     * example.
@@ -1180,6 +1194,7 @@ public final class Parcel {
     * growing dataCapacity() if needed.
     */
    public final void writeInt(int val) {
        assertNotRecycled();
        int err = nativeWriteInt(mNativePtr, val);
        if (err != OK) {
            nativeSignalExceptionForError(err);
@@ -3282,6 +3297,7 @@ public final class Parcel {
     * Read an integer value from the parcel at the current dataPosition().
     */
    public final int readInt() {
        assertNotRecycled();
        return nativeReadInt(mNativePtr);
    }