Loading core/api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -9678,6 +9678,7 @@ package android.content { method @Nullable public String getAttributionTag(); method @Nullable public android.content.AttributionSource getNext(); method @Nullable public String getPackageName(); method public int getPid(); method public int getUid(); method public boolean isTrusted(@NonNull android.content.Context); method @NonNull public static android.content.AttributionSource myAttributionSource(); Loading @@ -9692,6 +9693,7 @@ package android.content { method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@Nullable String); method @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource); method @NonNull public android.content.AttributionSource.Builder setPackageName(@Nullable String); method @NonNull public android.content.AttributionSource.Builder setPid(int); } public abstract class BroadcastReceiver { Loading Loading @@ -33610,6 +33612,7 @@ package android.os { method @Deprecated public static final boolean supportsProcesses(); field public static final int BLUETOOTH_UID = 1002; // 0x3ea field public static final int FIRST_APPLICATION_UID = 10000; // 0x2710 field public static final int INVALID_PID = -1; // 0xffffffff field public static final int INVALID_UID = -1; // 0xffffffff field public static final int LAST_APPLICATION_UID = 19999; // 0x4e1f field public static final int PHONE_UID = 1001; // 0x3e9 core/java/android/app/AppOpsManager.java +12 −11 Original line number Diff line number Diff line Loading @@ -8408,9 +8408,9 @@ public class AppOpsManager { public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) { return noteProxyOp(op, new AttributionSource(mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); new AttributionSource(proxiedUid, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } /** Loading Loading @@ -8495,8 +8495,9 @@ public class AppOpsManager { int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) { return noteProxyOpNoThrow(strOpToOp(op), new AttributionSource( mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource() .getToken())), message,/*skipProxyOperation*/ false); Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } /** Loading Loading @@ -8906,9 +8907,9 @@ public class AppOpsManager { public int startProxyOp(@NonNull String op, int proxiedUid, @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag, @Nullable String message) { return startProxyOp(op, new AttributionSource(mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); new AttributionSource(proxiedUid, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } /** Loading Loading @@ -8954,7 +8955,7 @@ public class AppOpsManager { @Nullable String message) { return startProxyOpNoThrow(AppOpsManager.strOpToOp(op), new AttributionSource( mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } Loading Loading @@ -9103,8 +9104,8 @@ public class AppOpsManager { @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag) { IBinder token = mContext.getAttributionSource().getToken(); finishProxyOp(token, op, new AttributionSource(mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, token)), /*skipProxyOperation*/ false); new AttributionSource(proxiedUid, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, token)), /*skipProxyOperation*/ false); } /** Loading core/java/android/app/ContextImpl.java +3 −1 Original line number Diff line number Diff line Loading @@ -3461,7 +3461,9 @@ class ContextImpl extends Context { @Nullable AttributionSource nextAttributionSource, @Nullable Set<String> renouncedPermissions) { AttributionSource attributionSource = new AttributionSource(Process.myUid(), mOpPackageName, attributionTag, renouncedPermissions, nextAttributionSource); Process.myPid(), mOpPackageName, attributionTag, (renouncedPermissions != null) ? renouncedPermissions.toArray(new String[0]) : null, nextAttributionSource); // 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) { Loading core/java/android/content/AttributionSource.java +96 −45 Original line number Diff line number Diff line Loading @@ -101,22 +101,28 @@ public final class AttributionSource implements Parcelable { @TestApi public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag) { this(uid, packageName, attributionTag, sDefaultToken); this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken); } /** @hide */ public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag) { this(uid, pid, packageName, attributionTag, sDefaultToken); } /** @hide */ @TestApi public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token) { this(uid, packageName, attributionTag, token, /*renouncedPermissions*/ null, /*next*/ null); this(uid, Process.INVALID_PID, packageName, attributionTag, token, /*renouncedPermissions*/ null, /*next*/ null); } /** @hide */ public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token, @Nullable AttributionSource next) { this(uid, packageName, attributionTag, token, /*renouncedPermissions*/ null, next); public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token) { this(uid, pid, packageName, attributionTag, token, /*renouncedPermissions*/ null, /*next*/ null); } /** @hide */ Loading @@ -124,26 +130,33 @@ public final class AttributionSource implements Parcelable { public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable Set<String> renouncedPermissions, @Nullable AttributionSource next) { this(uid, packageName, attributionTag, (renouncedPermissions != null) ? renouncedPermissions.toArray(new String[0]) : null, next); this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken, (renouncedPermissions != null) ? renouncedPermissions.toArray(new String[0]) : null, /*next*/ next); } /** @hide */ public AttributionSource(@NonNull AttributionSource current, @Nullable AttributionSource next) { this(current.getUid(), current.getPackageName(), current.getAttributionTag(), current.getToken(), current.mAttributionSourceState.renouncedPermissions, next); this(current.getUid(), current.getPid(), current.getPackageName(), current.getAttributionTag(), current.getToken(), current.mAttributionSourceState.renouncedPermissions, next); } AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String[] renouncedPermissions, @Nullable AttributionSource next) { this(uid, packageName, attributionTag, sDefaultToken, renouncedPermissions, next); /** @hide */ public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String[] renouncedPermissions, @Nullable AttributionSource next) { this(uid, pid, packageName, attributionTag, sDefaultToken, renouncedPermissions, next); } AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token, @Nullable String[] renouncedPermissions, /** @hide */ public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token, @Nullable String[] renouncedPermissions, @Nullable AttributionSource next) { mAttributionSourceState = new AttributionSourceState(); mAttributionSourceState.uid = uid; mAttributionSourceState.pid = pid; mAttributionSourceState.token = token; mAttributionSourceState.packageName = packageName; mAttributionSourceState.attributionTag = attributionTag; Loading @@ -162,7 +175,17 @@ public final class AttributionSource implements Parcelable { // 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(); enforceCallingUid(); // If this object is being constructed as part of a oneway Binder call, getCallingPid will // return 0 instead of the true PID. In that case, invalidate the PID by setting it to // INVALID_PID (-1). final int callingPid = Binder.getCallingPid(); if (callingPid == 0) { mAttributionSourceState.pid = Process.INVALID_PID; } enforceCallingPid(); } /** @hide */ Loading @@ -172,22 +195,28 @@ public final class AttributionSource implements Parcelable { /** @hide */ public AttributionSource withNextAttributionSource(@Nullable AttributionSource next) { return new AttributionSource(getUid(), getPackageName(), getAttributionTag(), mAttributionSourceState.renouncedPermissions, next); return new AttributionSource(getUid(), getPid(), getPackageName(), getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, next); } /** @hide */ public AttributionSource withPackageName(@Nullable String packageName) { return new AttributionSource(getUid(), packageName, getAttributionTag(), mAttributionSourceState.renouncedPermissions, getNext()); return new AttributionSource(getUid(), getPid(), packageName, getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, getNext()); } /** @hide */ public AttributionSource withToken(@NonNull Binder token) { return new AttributionSource(getUid(), getPackageName(), getAttributionTag(), return new AttributionSource(getUid(), getPid(), getPackageName(), getAttributionTag(), token, mAttributionSourceState.renouncedPermissions, getNext()); } /** @hide */ public AttributionSource withPid(int pid) { return new AttributionSource(getUid(), pid, getPackageName(), getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, getNext()); } /** @hide */ public @NonNull AttributionSourceState asState() { return mAttributionSourceState; Loading Loading @@ -228,6 +257,7 @@ public final class AttributionSource implements Parcelable { } try { return new AttributionSource.Builder(uid) .setPid(Process.myPid()) .setPackageName(AppGlobals.getPackageManager().getPackagesForUid(uid)[0]) .build(); } catch (Exception ignored) { Loading Loading @@ -264,18 +294,6 @@ public final class AttributionSource implements Parcelable { } } /** * If you are handling an IPC and you don't trust the caller you need to validate whether the * attribution source is one for the calling app to prevent the caller to pass you a source from * another app without including themselves in the attribution chain. * * @throws SecurityException if the attribution source cannot be trusted to be from the caller. */ private void enforceCallingUidAndPid() { enforceCallingUid(); enforceCallingPid(); } /** * If you are handling an IPC and you don't trust the caller you need to validate * whether the attribution source is one for the calling app to prevent the caller Loading Loading @@ -312,7 +330,10 @@ public final class AttributionSource implements Parcelable { } /** * Validate that the pid being claimed for the calling app is not spoofed * Validate that the pid being claimed for the calling app is not spoofed. * * Note that the PID may be unavailable, for example if we're in a oneway Binder call. In this * case, calling enforceCallingPid is guaranteed to fail. The caller should anticipate this. * * @throws SecurityException if the attribution source cannot be trusted to be from the caller. * @hide Loading @@ -320,10 +341,14 @@ public final class AttributionSource implements Parcelable { @TestApi public void enforceCallingPid() { if (!checkCallingPid()) { if (Binder.getCallingPid() == 0) { throw new SecurityException("Calling pid unavailable due to oneway Binder call."); } else { throw new SecurityException("Calling pid: " + Binder.getCallingPid() + " doesn't match source pid: " + mAttributionSourceState.pid); } } } /** * Validate that the pid being claimed for the calling app is not spoofed Loading @@ -332,7 +357,8 @@ public final class AttributionSource implements Parcelable { */ private boolean checkCallingPid() { final int callingPid = Binder.getCallingPid(); if (mAttributionSourceState.pid != -1 && callingPid != mAttributionSourceState.pid) { if (mAttributionSourceState.pid != Process.INVALID_PID && callingPid != mAttributionSourceState.pid) { return false; } return true; Loading Loading @@ -448,6 +474,13 @@ public final class AttributionSource implements Parcelable { return mAttributionSourceState.uid; } /** * The PID that is accessing the permission protected data. */ public int getPid() { return mAttributionSourceState.pid; } /** * The package that is accessing the permission protected data. */ Loading Loading @@ -551,6 +584,7 @@ public final class AttributionSource implements Parcelable { throw new IllegalArgumentException("current AttributionSource can not be null"); } mAttributionSourceState.uid = current.getUid(); mAttributionSourceState.pid = current.getPid(); mAttributionSourceState.packageName = current.getPackageName(); mAttributionSourceState.attributionTag = current.getAttributionTag(); mAttributionSourceState.token = current.getToken(); Loading @@ -558,12 +592,26 @@ public final class AttributionSource implements Parcelable { current.mAttributionSourceState.renouncedPermissions; } /** * The PID of the process that is accessing the permission protected data. * * If not called, pid will default to {@link Process@INVALID_PID} (-1). This indicates that * the PID data is missing. Supplying a PID is not required, but recommended when * accessible. */ public @NonNull Builder setPid(int value) { checkNotUsed(); mBuilderFieldsSet |= 0x2; mAttributionSourceState.pid = value; return this; } /** * The package that is accessing the permission protected data. */ public @NonNull Builder setPackageName(@Nullable String value) { checkNotUsed(); mBuilderFieldsSet |= 0x2; mBuilderFieldsSet |= 0x4; mAttributionSourceState.packageName = value; return this; } Loading @@ -573,7 +621,7 @@ public final class AttributionSource implements Parcelable { */ public @NonNull Builder setAttributionTag(@Nullable String value) { checkNotUsed(); mBuilderFieldsSet |= 0x4; mBuilderFieldsSet |= 0x8; mAttributionSourceState.attributionTag = value; return this; } Loading Loading @@ -606,7 +654,7 @@ public final class AttributionSource implements Parcelable { @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public @NonNull Builder setRenouncedPermissions(@Nullable Set<String> value) { checkNotUsed(); mBuilderFieldsSet |= 0x8; mBuilderFieldsSet |= 0x10; mAttributionSourceState.renouncedPermissions = (value != null) ? value.toArray(new String[0]) : null; return this; Loading @@ -617,7 +665,7 @@ public final class AttributionSource implements Parcelable { */ public @NonNull Builder setNext(@Nullable AttributionSource value) { checkNotUsed(); mBuilderFieldsSet |= 0x10; mBuilderFieldsSet |= 0x20; mAttributionSourceState.next = (value != null) ? new AttributionSourceState[] {value.mAttributionSourceState} : mAttributionSourceState.next; return this; Loading @@ -629,15 +677,18 @@ public final class AttributionSource implements Parcelable { mBuilderFieldsSet |= 0x40; // Mark builder used if ((mBuilderFieldsSet & 0x2) == 0) { mAttributionSourceState.packageName = null; mAttributionSourceState.pid = Process.INVALID_PID; } if ((mBuilderFieldsSet & 0x4) == 0) { mAttributionSourceState.attributionTag = null; mAttributionSourceState.packageName = null; } if ((mBuilderFieldsSet & 0x8) == 0) { mAttributionSourceState.renouncedPermissions = null; mAttributionSourceState.attributionTag = null; } if ((mBuilderFieldsSet & 0x10) == 0) { mAttributionSourceState.renouncedPermissions = null; } if ((mBuilderFieldsSet & 0x20) == 0) { mAttributionSourceState.next = null; } Loading core/java/android/content/PermissionChecker.java +1 −1 Original line number Diff line number Diff line Loading @@ -152,7 +152,7 @@ public final class PermissionChecker { @NonNull String permission, int pid, int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String message, boolean startDataDelivery) { return checkPermissionForDataDelivery(context, permission, pid, new AttributionSource(uid, packageName, attributionTag), message, startDataDelivery); pid, packageName, attributionTag), message, startDataDelivery); } /** Loading Loading
core/api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -9678,6 +9678,7 @@ package android.content { method @Nullable public String getAttributionTag(); method @Nullable public android.content.AttributionSource getNext(); method @Nullable public String getPackageName(); method public int getPid(); method public int getUid(); method public boolean isTrusted(@NonNull android.content.Context); method @NonNull public static android.content.AttributionSource myAttributionSource(); Loading @@ -9692,6 +9693,7 @@ package android.content { method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@Nullable String); method @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource); method @NonNull public android.content.AttributionSource.Builder setPackageName(@Nullable String); method @NonNull public android.content.AttributionSource.Builder setPid(int); } public abstract class BroadcastReceiver { Loading Loading @@ -33610,6 +33612,7 @@ package android.os { method @Deprecated public static final boolean supportsProcesses(); field public static final int BLUETOOTH_UID = 1002; // 0x3ea field public static final int FIRST_APPLICATION_UID = 10000; // 0x2710 field public static final int INVALID_PID = -1; // 0xffffffff field public static final int INVALID_UID = -1; // 0xffffffff field public static final int LAST_APPLICATION_UID = 19999; // 0x4e1f field public static final int PHONE_UID = 1001; // 0x3e9
core/java/android/app/AppOpsManager.java +12 −11 Original line number Diff line number Diff line Loading @@ -8408,9 +8408,9 @@ public class AppOpsManager { public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) { return noteProxyOp(op, new AttributionSource(mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); new AttributionSource(proxiedUid, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } /** Loading Loading @@ -8495,8 +8495,9 @@ public class AppOpsManager { int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) { return noteProxyOpNoThrow(strOpToOp(op), new AttributionSource( mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource() .getToken())), message,/*skipProxyOperation*/ false); Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } /** Loading Loading @@ -8906,9 +8907,9 @@ public class AppOpsManager { public int startProxyOp(@NonNull String op, int proxiedUid, @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag, @Nullable String message) { return startProxyOp(op, new AttributionSource(mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); new AttributionSource(proxiedUid, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } /** Loading Loading @@ -8954,7 +8955,7 @@ public class AppOpsManager { @Nullable String message) { return startProxyOpNoThrow(AppOpsManager.strOpToOp(op), new AttributionSource( mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource().getToken())), message, /*skipProxyOperation*/ false); } Loading Loading @@ -9103,8 +9104,8 @@ public class AppOpsManager { @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag) { IBinder token = mContext.getAttributionSource().getToken(); finishProxyOp(token, op, new AttributionSource(mContext.getAttributionSource(), new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, token)), /*skipProxyOperation*/ false); new AttributionSource(proxiedUid, Process.INVALID_PID, proxiedPackageName, proxiedAttributionTag, token)), /*skipProxyOperation*/ false); } /** Loading
core/java/android/app/ContextImpl.java +3 −1 Original line number Diff line number Diff line Loading @@ -3461,7 +3461,9 @@ class ContextImpl extends Context { @Nullable AttributionSource nextAttributionSource, @Nullable Set<String> renouncedPermissions) { AttributionSource attributionSource = new AttributionSource(Process.myUid(), mOpPackageName, attributionTag, renouncedPermissions, nextAttributionSource); Process.myPid(), mOpPackageName, attributionTag, (renouncedPermissions != null) ? renouncedPermissions.toArray(new String[0]) : null, nextAttributionSource); // 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) { Loading
core/java/android/content/AttributionSource.java +96 −45 Original line number Diff line number Diff line Loading @@ -101,22 +101,28 @@ public final class AttributionSource implements Parcelable { @TestApi public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag) { this(uid, packageName, attributionTag, sDefaultToken); this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken); } /** @hide */ public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag) { this(uid, pid, packageName, attributionTag, sDefaultToken); } /** @hide */ @TestApi public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token) { this(uid, packageName, attributionTag, token, /*renouncedPermissions*/ null, /*next*/ null); this(uid, Process.INVALID_PID, packageName, attributionTag, token, /*renouncedPermissions*/ null, /*next*/ null); } /** @hide */ public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token, @Nullable AttributionSource next) { this(uid, packageName, attributionTag, token, /*renouncedPermissions*/ null, next); public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token) { this(uid, pid, packageName, attributionTag, token, /*renouncedPermissions*/ null, /*next*/ null); } /** @hide */ Loading @@ -124,26 +130,33 @@ public final class AttributionSource implements Parcelable { public AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable Set<String> renouncedPermissions, @Nullable AttributionSource next) { this(uid, packageName, attributionTag, (renouncedPermissions != null) ? renouncedPermissions.toArray(new String[0]) : null, next); this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken, (renouncedPermissions != null) ? renouncedPermissions.toArray(new String[0]) : null, /*next*/ next); } /** @hide */ public AttributionSource(@NonNull AttributionSource current, @Nullable AttributionSource next) { this(current.getUid(), current.getPackageName(), current.getAttributionTag(), current.getToken(), current.mAttributionSourceState.renouncedPermissions, next); this(current.getUid(), current.getPid(), current.getPackageName(), current.getAttributionTag(), current.getToken(), current.mAttributionSourceState.renouncedPermissions, next); } AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String[] renouncedPermissions, @Nullable AttributionSource next) { this(uid, packageName, attributionTag, sDefaultToken, renouncedPermissions, next); /** @hide */ public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String[] renouncedPermissions, @Nullable AttributionSource next) { this(uid, pid, packageName, attributionTag, sDefaultToken, renouncedPermissions, next); } AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token, @Nullable String[] renouncedPermissions, /** @hide */ public AttributionSource(int uid, int pid, @Nullable String packageName, @Nullable String attributionTag, @NonNull IBinder token, @Nullable String[] renouncedPermissions, @Nullable AttributionSource next) { mAttributionSourceState = new AttributionSourceState(); mAttributionSourceState.uid = uid; mAttributionSourceState.pid = pid; mAttributionSourceState.token = token; mAttributionSourceState.packageName = packageName; mAttributionSourceState.attributionTag = attributionTag; Loading @@ -162,7 +175,17 @@ public final class AttributionSource implements Parcelable { // 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(); enforceCallingUid(); // If this object is being constructed as part of a oneway Binder call, getCallingPid will // return 0 instead of the true PID. In that case, invalidate the PID by setting it to // INVALID_PID (-1). final int callingPid = Binder.getCallingPid(); if (callingPid == 0) { mAttributionSourceState.pid = Process.INVALID_PID; } enforceCallingPid(); } /** @hide */ Loading @@ -172,22 +195,28 @@ public final class AttributionSource implements Parcelable { /** @hide */ public AttributionSource withNextAttributionSource(@Nullable AttributionSource next) { return new AttributionSource(getUid(), getPackageName(), getAttributionTag(), mAttributionSourceState.renouncedPermissions, next); return new AttributionSource(getUid(), getPid(), getPackageName(), getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, next); } /** @hide */ public AttributionSource withPackageName(@Nullable String packageName) { return new AttributionSource(getUid(), packageName, getAttributionTag(), mAttributionSourceState.renouncedPermissions, getNext()); return new AttributionSource(getUid(), getPid(), packageName, getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, getNext()); } /** @hide */ public AttributionSource withToken(@NonNull Binder token) { return new AttributionSource(getUid(), getPackageName(), getAttributionTag(), return new AttributionSource(getUid(), getPid(), getPackageName(), getAttributionTag(), token, mAttributionSourceState.renouncedPermissions, getNext()); } /** @hide */ public AttributionSource withPid(int pid) { return new AttributionSource(getUid(), pid, getPackageName(), getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, getNext()); } /** @hide */ public @NonNull AttributionSourceState asState() { return mAttributionSourceState; Loading Loading @@ -228,6 +257,7 @@ public final class AttributionSource implements Parcelable { } try { return new AttributionSource.Builder(uid) .setPid(Process.myPid()) .setPackageName(AppGlobals.getPackageManager().getPackagesForUid(uid)[0]) .build(); } catch (Exception ignored) { Loading Loading @@ -264,18 +294,6 @@ public final class AttributionSource implements Parcelable { } } /** * If you are handling an IPC and you don't trust the caller you need to validate whether the * attribution source is one for the calling app to prevent the caller to pass you a source from * another app without including themselves in the attribution chain. * * @throws SecurityException if the attribution source cannot be trusted to be from the caller. */ private void enforceCallingUidAndPid() { enforceCallingUid(); enforceCallingPid(); } /** * If you are handling an IPC and you don't trust the caller you need to validate * whether the attribution source is one for the calling app to prevent the caller Loading Loading @@ -312,7 +330,10 @@ public final class AttributionSource implements Parcelable { } /** * Validate that the pid being claimed for the calling app is not spoofed * Validate that the pid being claimed for the calling app is not spoofed. * * Note that the PID may be unavailable, for example if we're in a oneway Binder call. In this * case, calling enforceCallingPid is guaranteed to fail. The caller should anticipate this. * * @throws SecurityException if the attribution source cannot be trusted to be from the caller. * @hide Loading @@ -320,10 +341,14 @@ public final class AttributionSource implements Parcelable { @TestApi public void enforceCallingPid() { if (!checkCallingPid()) { if (Binder.getCallingPid() == 0) { throw new SecurityException("Calling pid unavailable due to oneway Binder call."); } else { throw new SecurityException("Calling pid: " + Binder.getCallingPid() + " doesn't match source pid: " + mAttributionSourceState.pid); } } } /** * Validate that the pid being claimed for the calling app is not spoofed Loading @@ -332,7 +357,8 @@ public final class AttributionSource implements Parcelable { */ private boolean checkCallingPid() { final int callingPid = Binder.getCallingPid(); if (mAttributionSourceState.pid != -1 && callingPid != mAttributionSourceState.pid) { if (mAttributionSourceState.pid != Process.INVALID_PID && callingPid != mAttributionSourceState.pid) { return false; } return true; Loading Loading @@ -448,6 +474,13 @@ public final class AttributionSource implements Parcelable { return mAttributionSourceState.uid; } /** * The PID that is accessing the permission protected data. */ public int getPid() { return mAttributionSourceState.pid; } /** * The package that is accessing the permission protected data. */ Loading Loading @@ -551,6 +584,7 @@ public final class AttributionSource implements Parcelable { throw new IllegalArgumentException("current AttributionSource can not be null"); } mAttributionSourceState.uid = current.getUid(); mAttributionSourceState.pid = current.getPid(); mAttributionSourceState.packageName = current.getPackageName(); mAttributionSourceState.attributionTag = current.getAttributionTag(); mAttributionSourceState.token = current.getToken(); Loading @@ -558,12 +592,26 @@ public final class AttributionSource implements Parcelable { current.mAttributionSourceState.renouncedPermissions; } /** * The PID of the process that is accessing the permission protected data. * * If not called, pid will default to {@link Process@INVALID_PID} (-1). This indicates that * the PID data is missing. Supplying a PID is not required, but recommended when * accessible. */ public @NonNull Builder setPid(int value) { checkNotUsed(); mBuilderFieldsSet |= 0x2; mAttributionSourceState.pid = value; return this; } /** * The package that is accessing the permission protected data. */ public @NonNull Builder setPackageName(@Nullable String value) { checkNotUsed(); mBuilderFieldsSet |= 0x2; mBuilderFieldsSet |= 0x4; mAttributionSourceState.packageName = value; return this; } Loading @@ -573,7 +621,7 @@ public final class AttributionSource implements Parcelable { */ public @NonNull Builder setAttributionTag(@Nullable String value) { checkNotUsed(); mBuilderFieldsSet |= 0x4; mBuilderFieldsSet |= 0x8; mAttributionSourceState.attributionTag = value; return this; } Loading Loading @@ -606,7 +654,7 @@ public final class AttributionSource implements Parcelable { @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public @NonNull Builder setRenouncedPermissions(@Nullable Set<String> value) { checkNotUsed(); mBuilderFieldsSet |= 0x8; mBuilderFieldsSet |= 0x10; mAttributionSourceState.renouncedPermissions = (value != null) ? value.toArray(new String[0]) : null; return this; Loading @@ -617,7 +665,7 @@ public final class AttributionSource implements Parcelable { */ public @NonNull Builder setNext(@Nullable AttributionSource value) { checkNotUsed(); mBuilderFieldsSet |= 0x10; mBuilderFieldsSet |= 0x20; mAttributionSourceState.next = (value != null) ? new AttributionSourceState[] {value.mAttributionSourceState} : mAttributionSourceState.next; return this; Loading @@ -629,15 +677,18 @@ public final class AttributionSource implements Parcelable { mBuilderFieldsSet |= 0x40; // Mark builder used if ((mBuilderFieldsSet & 0x2) == 0) { mAttributionSourceState.packageName = null; mAttributionSourceState.pid = Process.INVALID_PID; } if ((mBuilderFieldsSet & 0x4) == 0) { mAttributionSourceState.attributionTag = null; mAttributionSourceState.packageName = null; } if ((mBuilderFieldsSet & 0x8) == 0) { mAttributionSourceState.renouncedPermissions = null; mAttributionSourceState.attributionTag = null; } if ((mBuilderFieldsSet & 0x10) == 0) { mAttributionSourceState.renouncedPermissions = null; } if ((mBuilderFieldsSet & 0x20) == 0) { mAttributionSourceState.next = null; } Loading
core/java/android/content/PermissionChecker.java +1 −1 Original line number Diff line number Diff line Loading @@ -152,7 +152,7 @@ public final class PermissionChecker { @NonNull String permission, int pid, int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String message, boolean startDataDelivery) { return checkPermissionForDataDelivery(context, permission, pid, new AttributionSource(uid, packageName, attributionTag), message, startDataDelivery); pid, packageName, attributionTag), message, startDataDelivery); } /** Loading