Fix vulnerability in AttributionSource due to incorrect Binder call

AttributionSource uses Binder.getCallingUid to verify the UID of the
caller from another process. However, getCallingUid does not always
behave as expected. If the AttributionSource is unparceled outside a
transaction thread, which is quite possible, getCallingUid will return
the UID of the current process instead. If this is a system process,
the UID check gets bypassed entirely, meaning any uid can be provided.

This patch fixes the vulnerability by emptying out the state of the
AttributionSource, so that the service checking its credentials will
fail to give permission to the app.

Bug: 267231571
Test: v2/android-virtual-infra/test_mapping/presubmit-avd
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5d79e535b9a802680062545e15fc1faaf779c0bf)
Merged-In: I3f228064fbd62e1c907f1ebe870cb61102f788f0
Change-Id: I3f228064fbd62e1c907f1ebe870cb61102f788f0
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index 3f2fa21..16b18c85 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -31,6 +31,7 @@
 import android.os.Process;
 import android.permission.PermissionManager;
 import android.util.ArraySet;
+import android.util.Log;
 
 import com.android.internal.annotations.Immutable;
 
@@ -87,6 +88,8 @@
  */
 @Immutable
 public final class AttributionSource implements Parcelable {
+    private static final String TAG = "AttributionSource";
+
     private static final String DESCRIPTOR = "android.content.AttributionSource";
 
     private static final Binder sDefaultToken = new Binder(DESCRIPTOR);
@@ -154,9 +157,20 @@
     AttributionSource(@NonNull Parcel in) {
         this(AttributionSourceState.CREATOR.createFromParcel(in));
 
-        // Since we just unpacked this object as part of it transiting a Binder
-        // call, this is the perfect time to enforce that its UID and PID can be trusted
-        enforceCallingUidAndPid();
+        if (!Binder.isDirectlyHandlingTransaction()) {
+            Log.e(TAG, "Unable to verify calling UID #" + mAttributionSourceState.uid + " PID #"
+                    + mAttributionSourceState.pid + " when not handling Binder transaction; "
+                    + "clearing.");
+            mAttributionSourceState.pid = -1;
+            mAttributionSourceState.uid = -1;
+            mAttributionSourceState.packageName = null;
+            mAttributionSourceState.attributionTag = null;
+            mAttributionSourceState.next = null;
+        } else {
+            // Since we just unpacked this object as part of it transiting a Binder
+            // call, this is the perfect time to enforce that its UID and PID can be trusted
+            enforceCallingUidAndPid();
+        }
     }
 
     /** @hide */