From 1babd5bf516be8ffbd649a59dc136a9cdac24ba4 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Fri, 9 Jul 2021 22:07:12 +0000 Subject: [PATCH] Optimize AttributionSource tokens - base For cases where the attribution soruce doesn't need to be registered as trusted we are now using a shares static token since the only purpose of the token in these cases is for watching the source process dying as opposed to that and security for registered cases. bug: 192415943 Test: CtsPermissionTestCases CtsPermission2TestCases CtsPermission3TestCases CtsPermission4TestCases CtsPermission5TestCases Change-Id: I93fde9ca1cacada7929761533dcae11b2736ce1e --- core/api/test-current.txt | 2 +- core/java/android/app/ContextImpl.java | 3 ++- core/java/android/content/AttributionSource.java | 16 +++++++++++++--- .../android/permission/PermissionManager.java | 11 +++++++++-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 3be40042ad58f..dd7c6db5d8fbe 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2068,7 +2068,7 @@ package android.permission { public final class PermissionManager { method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List getIndicatorAppOpUsageData(); method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List getIndicatorAppOpUsageData(boolean); - method public void registerAttributionSource(@NonNull android.content.AttributionSource); + method @NonNull public android.content.AttributionSource registerAttributionSource(@NonNull android.content.AttributionSource); } } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 5e99c79a74978..f52fdc562b132 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -3149,7 +3149,8 @@ class ContextImpl extends Context { // If we want to access protected data on behalf of another app we need to // tell the OS that we opt in to participate in the attribution chain. if (nextAttributionSource != null) { - getSystemService(PermissionManager.class).registerAttributionSource(attributionSource); + attributionSource = getSystemService(PermissionManager.class) + .registerAttributionSource(attributionSource); } return attributionSource; } diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java index c499f691b69ae..d63ce0f4a9438 100644 --- a/core/java/android/content/AttributionSource.java +++ b/core/java/android/content/AttributionSource.java @@ -88,6 +88,8 @@ import java.util.Set; public final class AttributionSource implements Parcelable { private static final String DESCRIPTOR = "android.content.AttributionSource"; + private static final Binder sDefaultToken = new Binder(DESCRIPTOR); + private final @NonNull AttributionSourceState mAttributionSourceState; private @Nullable AttributionSource mNextCached; @@ -97,7 +99,7 @@ public final class AttributionSource implements Parcelable { @TestApi public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag) { - this(uid, packageName, attributionTag, new Binder(DESCRIPTOR)); + this(uid, packageName, attributionTag, sDefaultToken); } /** @hide */ @@ -132,7 +134,7 @@ public final class AttributionSource implements Parcelable { AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String[] renouncedPermissions, @Nullable AttributionSource next) { - this(uid, packageName, attributionTag, new Binder(DESCRIPTOR), renouncedPermissions, next); + this(uid, packageName, attributionTag, sDefaultToken, renouncedPermissions, next); } AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @@ -169,6 +171,12 @@ public final class AttributionSource implements Parcelable { mAttributionSourceState.renouncedPermissions, getNext()); } + /** @hide */ + public AttributionSource withToken(@NonNull Binder token) { + return new AttributionSource(getUid(), getPackageName(), getAttributionTag(), + token, mAttributionSourceState.renouncedPermissions, getNext()); + } + /** @hide */ public @NonNull AttributionSourceState asState() { return mAttributionSourceState; @@ -543,7 +551,9 @@ public final class AttributionSource implements Parcelable { if ((mBuilderFieldsSet & 0x10) == 0) { mAttributionSourceState.next = null; } - mAttributionSourceState.token = new Binder(DESCRIPTOR); + + mAttributionSourceState.token = sDefaultToken; + if (mAttributionSourceState.next == null) { // The NDK aidl backend doesn't support null parcelable arrays. mAttributionSourceState.next = new AttributionSourceState[0]; diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 4ef0e6e785e85..a52ede87880e0 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -44,6 +44,7 @@ import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.permission.SplitPermissionInfoParcelable; import android.media.AudioManager; +import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -1163,18 +1164,24 @@ public final class PermissionManager { * that doesn't participate in an attribution chain. * * @param source The attribution source to register. + * @return The registered new attribution source. * * @see #isRegisteredAttributionSource(AttributionSource) * * @hide */ @TestApi - public void registerAttributionSource(@NonNull AttributionSource source) { + public @NonNull AttributionSource registerAttributionSource(@NonNull AttributionSource source) { + // We use a shared static token for sources that are not registered since the token's + // only used for process death detection. If we are about to use the source for security + // enforcement we need to replace the binder with a unique one. + final AttributionSource registeredSource = source.withToken(new Binder()); try { - mPermissionManager.registerAttributionSource(source); + mPermissionManager.registerAttributionSource(registeredSource); } catch (RemoteException e) { e.rethrowFromSystemServer(); } + return registeredSource; } /**