diff options
10 files changed, 74 insertions, 33 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1b45d172cb89..497e193c38ec 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -6152,7 +6152,7 @@ public final class ActivityThread extends ClientTransactionHandler { try { synchronized (getGetProviderLock(auth, userId)) { holder = ActivityManager.getService().getContentProvider( - getApplicationThread(), auth, userId, stable); + getApplicationThread(), c.getOpPackageName(), auth, userId, stable); } } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 88fb025bf406..fb519b625012 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -124,7 +124,7 @@ interface IActivityManager { int ignoreWindowingMode); void moveTaskToFront(int task, int flags, in Bundle options); int getTaskForActivity(in IBinder token, in boolean onlyRoot); - ContentProviderHolder getContentProvider(in IApplicationThread caller, + ContentProviderHolder getContentProvider(in IApplicationThread caller, in String callingPackage, in String name, int userId, boolean stable); void publishContentProviders(in IApplicationThread caller, in List<ContentProviderHolder> providers); diff --git a/core/java/com/android/internal/app/procstats/AssociationState.java b/core/java/com/android/internal/app/procstats/AssociationState.java index 4da339165655..2df515835026 100644 --- a/core/java/com/android/internal/app/procstats/AssociationState.java +++ b/core/java/com/android/internal/app/procstats/AssociationState.java @@ -17,6 +17,7 @@ package com.android.internal.app.procstats; +import android.annotation.Nullable; import android.os.Parcel; import android.os.SystemClock; import android.os.UserHandle; @@ -192,9 +193,16 @@ public final class AssociationState { */ String mProcess; - SourceKey(int uid, String process) { + /** + * Optional package name, or null; consider this final. Not final just to avoid a + * temporary object during lookup. + */ + @Nullable String mPackage; + + SourceKey(int uid, String process, String pkg) { mUid = uid; mProcess = process; + mPackage = pkg; } public boolean equals(Object o) { @@ -202,12 +210,14 @@ public final class AssociationState { return false; } SourceKey s = (SourceKey) o; - return s.mUid == mUid && Objects.equals(s.mProcess, mProcess); + return s.mUid == mUid && Objects.equals(s.mProcess, mProcess) + && Objects.equals(s.mPackage, mPackage); } @Override public int hashCode() { - return Integer.hashCode(mUid) ^ (mProcess == null ? 0 : mProcess.hashCode()); + return Integer.hashCode(mUid) ^ (mProcess == null ? 0 : mProcess.hashCode()) + ^ (mPackage == null ? 0 : (mPackage.hashCode() * 33)); } @Override @@ -217,6 +227,8 @@ public final class AssociationState { UserHandle.formatUid(sb, mUid); sb.append(' '); sb.append(mProcess); + sb.append(' '); + sb.append(mPackage); sb.append('}'); return sb.toString(); } @@ -227,7 +239,7 @@ public final class AssociationState { */ private final ArrayMap<SourceKey, SourceState> mSources = new ArrayMap<>(); - private final SourceKey mTmpSourceKey = new SourceKey(0, null); + private final SourceKey mTmpSourceKey = new SourceKey(0, null, null); private ProcessState mProc; @@ -266,12 +278,13 @@ public final class AssociationState { mProc = proc; } - public SourceState startSource(int uid, String processName) { + public SourceState startSource(int uid, String processName, String packageName) { mTmpSourceKey.mUid = uid; mTmpSourceKey.mProcess = processName; + mTmpSourceKey.mPackage = packageName; SourceState src = mSources.get(mTmpSourceKey); if (src == null) { - SourceKey key = new SourceKey(uid, processName); + SourceKey key = new SourceKey(uid, processName, packageName); src = new SourceState(key); mSources.put(key, src); } @@ -379,6 +392,7 @@ public final class AssociationState { final SourceState src = mSources.valueAt(isrc); out.writeInt(key.mUid); stats.writeCommonString(out, key.mProcess); + stats.writeCommonString(out, key.mPackage); out.writeInt(src.mCount); out.writeLong(src.mDuration); out.writeInt(src.mActiveCount); @@ -405,7 +419,8 @@ public final class AssociationState { for (int isrc = 0; isrc < NSRC; isrc++) { final int uid = in.readInt(); final String procName = stats.readCommonString(in, parcelVersion); - final SourceKey key = new SourceKey(uid, procName); + final String pkgName = stats.readCommonString(in, parcelVersion); + final SourceKey key = new SourceKey(uid, procName, pkgName); final SourceState src = new SourceState(key); src.mCount = in.readInt(); src.mDuration = in.readLong(); @@ -445,10 +460,11 @@ public final class AssociationState { } } - public boolean hasProcess(String procName) { + public boolean hasProcessOrPackage(String procName) { final int NSRC = mSources.size(); for (int isrc = 0; isrc < NSRC; isrc++) { - if (mSources.keyAt(isrc).mProcess.equals(procName)) { + final SourceKey key = mSources.keyAt(isrc); + if (procName.equals(key.mProcess) || procName.equals(key.mPackage)) { return true; } } @@ -466,14 +482,20 @@ public final class AssociationState { for (int isrc = 0; isrc < NSRC; isrc++) { final SourceKey key = mSources.keyAt(isrc); final SourceState src = mSources.valueAt(isrc); - if (reqPackage != null && !reqPackage.equals(key.mProcess)) { + if (reqPackage != null && !reqPackage.equals(key.mProcess) + && !reqPackage.equals(key.mPackage)) { continue; } pw.print(prefixInner); pw.print("<- "); pw.print(key.mProcess); - pw.print(" / "); + pw.print("/"); UserHandle.formatUid(pw, key.mUid); + if (key.mPackage != null) { + pw.print(" ("); + pw.print(key.mPackage); + pw.print(")"); + } pw.println(":"); pw.print(prefixInner); pw.print(" Total count "); @@ -683,6 +705,7 @@ public final class AssociationState { final SourceState src = mSources.valueAt(isrc); final long sourceToken = proto.start(PackageAssociationProcessStatsProto.SOURCES); proto.write(PackageAssociationSourceProcessStatsProto.PROCESS_NAME, key.mProcess); + proto.write(PackageAssociationSourceProcessStatsProto.PACKAGE_NAME, key.mPackage); proto.write(PackageAssociationSourceProcessStatsProto.PROCESS_UID, key.mUid); proto.write(PackageAssociationSourceProcessStatsProto.TOTAL_COUNT, src.mCount); long duration = src.mDuration; diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java index 9ee583a97b8d..9b9b77196a53 100644 --- a/core/java/com/android/internal/app/procstats/ProcessStats.java +++ b/core/java/com/android/internal/app/procstats/ProcessStats.java @@ -178,7 +178,7 @@ public final class ProcessStats implements Parcelable { {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"}; // Current version of the parcel format. - private static final int PARCEL_VERSION = 34; + private static final int PARCEL_VERSION = 35; // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0x50535454; @@ -1490,7 +1490,7 @@ public final class ProcessStats implements Parcelable { // package, so that if so we print those. for (int iasc = 0; iasc < NASCS; iasc++) { AssociationState asc = pkgState.mAssociations.valueAt(iasc); - if (asc.hasProcess(reqPackage)) { + if (asc.hasProcessOrPackage(reqPackage)) { onlyAssociations = true; break; } @@ -1591,7 +1591,7 @@ public final class ProcessStats implements Parcelable { for (int iasc = 0; iasc < NASCS; iasc++) { AssociationState asc = pkgState.mAssociations.valueAt(iasc); if (!pkgMatch && !reqPackage.equals(asc.getProcessName())) { - if (!onlyAssociations || !asc.hasProcess(reqPackage)) { + if (!onlyAssociations || !asc.hasProcessOrPackage(reqPackage)) { continue; } } diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto index ce19ce3519b2..71ebcc1e3659 100644 --- a/core/proto/android/service/procstats.proto +++ b/core/proto/android/service/procstats.proto @@ -186,7 +186,7 @@ message PackageServiceStatsProto { repeated PackageServiceOperationStatsProto operation_stats = 2; } -// Next Tag: 7 +// Next Tag: 8 message PackageAssociationSourceProcessStatsProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; @@ -194,6 +194,8 @@ message PackageAssociationSourceProcessStatsProto { optional int32 process_uid = 1; // Process name. optional string process_name = 2; + // Package name. + optional string package_name = 7; // Total count of the times this association appeared. optional int32 total_count = 3; diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 5afb90d681af..fe632e52cae6 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1665,7 +1665,7 @@ public final class ActiveServices { AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); ConnectionRecord c = new ConnectionRecord(b, activity, connection, flags, clientLabel, clientIntent, - callerApp.uid, callerApp.processName); + callerApp.uid, callerApp.processName, callingPackage); IBinder binder = connection.asBinder(); ArrayList<ConnectionRecord> clist = s.connections.get(binder); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2cc4296816db..d11439755693 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6291,7 +6291,7 @@ public class ActivityManagerService extends IActivityManager.Stub ContentProviderConnection incProviderCountLocked(ProcessRecord r, final ContentProviderRecord cpr, IBinder externalProcessToken, int callingUid, - String callingTag, boolean stable) { + String callingPackage, String callingTag, boolean stable) { if (r != null) { for (int i=0; i<r.conProviders.size(); i++) { ContentProviderConnection conn = r.conProviders.get(i); @@ -6311,7 +6311,7 @@ public class ActivityManagerService extends IActivityManager.Stub return conn; } } - ContentProviderConnection conn = new ContentProviderConnection(cpr, r); + ContentProviderConnection conn = new ContentProviderConnection(cpr, r, callingPackage); conn.startAssociationIfNeeded(); if (stable) { conn.stableCount = 1; @@ -6418,8 +6418,8 @@ public class ActivityManagerService extends IActivityManager.Stub } private ContentProviderHolder getContentProviderImpl(IApplicationThread caller, - String name, IBinder token, int callingUid, String callingTag, boolean stable, - int userId) { + String name, IBinder token, int callingUid, String callingPackage, String callingTag, + boolean stable, int userId) { ContentProviderRecord cpr; ContentProviderConnection conn = null; ProviderInfo cpi = null; @@ -6542,7 +6542,8 @@ public class ActivityManagerService extends IActivityManager.Stub // In this case the provider instance already exists, so we can // return it right away. - conn = incProviderCountLocked(r, cpr, token, callingUid, callingTag, stable); + conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag, + stable); if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { // If this is a perceptible app accessing the provider, @@ -6789,7 +6790,8 @@ public class ActivityManagerService extends IActivityManager.Stub } mProviderMap.putProviderByName(name, cpr); - conn = incProviderCountLocked(r, cpr, token, callingUid, callingTag, stable); + conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag, + stable); if (conn != null) { conn.waiting = true; } @@ -6931,7 +6933,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final ContentProviderHolder getContentProvider( - IApplicationThread caller, String name, int userId, boolean stable) { + IApplicationThread caller, String callingPackage, String name, int userId, + boolean stable) { enforceNotIsolatedCaller("getContentProvider"); if (caller == null) { String msg = "null IApplicationThread when getting content provider " @@ -6941,8 +6944,14 @@ public class ActivityManagerService extends IActivityManager.Stub } // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal // with cross-user grant. - return getContentProviderImpl(caller, name, null, Binder.getCallingUid(), null, stable, - userId); + final int callingUid = Binder.getCallingUid(); + if (callingPackage != null && mAppOpsService.checkPackage(callingUid, callingPackage) + != AppOpsManager.MODE_ALLOWED) { + throw new SecurityException("Given calling package " + callingPackage + + " does not match caller's uid " + callingUid); + } + return getContentProviderImpl(caller, name, null, callingUid, callingPackage, + null, stable, userId); } public ContentProviderHolder getContentProviderExternal( @@ -6957,7 +6966,8 @@ public class ActivityManagerService extends IActivityManager.Stub private ContentProviderHolder getContentProviderExternalUnchecked(String name, IBinder token, int callingUid, String callingTag, int userId) { - return getContentProviderImpl(null, name, token, callingUid, callingTag, true, userId); + return getContentProviderImpl(null, name, token, callingUid, null, callingTag, + true, userId); } /** diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index aa76b3d6b856..af1031e5b887 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -43,6 +43,7 @@ final class ConnectionRecord { final PendingIntent clientIntent; // How to launch the client. final int clientUid; // The identity of this connection's client final String clientProcessName; // The source process of this connection's client + final String clientPackageName; // The source package of this connection's client public AssociationState.SourceState association; // Association tracking String stringName; // Caching of toString. boolean serviceDead; // Well is it? @@ -96,7 +97,7 @@ final class ConnectionRecord { ActivityServiceConnectionsHolder<ConnectionRecord> _activity, IServiceConnection _conn, int _flags, int _clientLabel, PendingIntent _clientIntent, - int _clientUid, String _clientProcessName) { + int _clientUid, String _clientProcessName, String _clientPackageName) { binding = _binding; activity = _activity; conn = _conn; @@ -105,6 +106,7 @@ final class ConnectionRecord { clientIntent = _clientIntent; clientUid = _clientUid; clientProcessName = _clientProcessName; + clientPackageName = _clientPackageName; } public void startAssociationIfNeeded() { @@ -125,7 +127,7 @@ final class ConnectionRecord { } else { association = holder.pkg.getAssociationStateLocked(holder.state, binding.service.instanceName.getClassName()).startSource(clientUid, - clientProcessName); + clientProcessName, clientPackageName); } } diff --git a/services/core/java/com/android/server/am/ContentProviderConnection.java b/services/core/java/com/android/server/am/ContentProviderConnection.java index f2d4f739c8bf..5f184c2dabee 100644 --- a/services/core/java/com/android/server/am/ContentProviderConnection.java +++ b/services/core/java/com/android/server/am/ContentProviderConnection.java @@ -32,6 +32,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; public final class ContentProviderConnection extends Binder { public final ContentProviderRecord provider; public final ProcessRecord client; + public final String clientPackage; public AssociationState.SourceState association; public final long createTime; public int stableCount; @@ -46,9 +47,11 @@ public final class ContentProviderConnection extends Binder { public int numStableIncs; public int numUnstableIncs; - public ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client) { + public ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client, + String _clientPackage) { provider = _provider; client = _client; + clientPackage = _clientPackage; createTime = SystemClock.elapsedRealtime(); } @@ -69,7 +72,8 @@ public final class ContentProviderConnection extends Binder { + provider.name.toShortString() + ": proc=" + provider.proc); } else { association = holder.pkg.getAssociationStateLocked(holder.state, - provider.name.getClassName()).startSource(client.uid, client.processName); + provider.name.getClassName()).startSource(client.uid, client.processName, + clientPackage); } } diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java index 2fc4adc2dc6c..46dfc7c60fd9 100644 --- a/services/core/java/com/android/server/am/ContentProviderRecord.java +++ b/services/core/java/com/android/server/am/ContentProviderRecord.java @@ -305,7 +305,7 @@ final class ContentProviderRecord implements ComponentName.WithComponentName { } else { mAssociation = holder.pkg.getAssociationStateLocked(holder.state, provider.name.getClassName()).startSource(mOwningUid, - mOwningProcessName); + mOwningProcessName, null); } } |