From b059bd3947610c40cedc20ed02e0e1c4d9c237b2 Mon Sep 17 00:00:00 2001 From: Patrick Baumann Date: Fri, 6 Mar 2020 10:34:17 -0800 Subject: Do not set referrerUri on SessionInfo for non-owners This change leaves the referrerUri field null when the caller leading to its production is not the owner of the session. Bug: 142125338 Test: atest SessionReferrerUriTest Merged-In: I84679ea0636aa2097e25e23813c48134c9cc1d75 Change-Id: I84679ea0636aa2097e25e23813c48134c9cc1d75 --- core/java/android/content/pm/PackageInstaller.java | 2 + .../android/server/pm/PackageInstallerService.java | 20 +++++++--- .../android/server/pm/PackageInstallerSession.java | 46 +++++++++++++++++++--- .../java/com/android/server/pm/StagingManager.java | 5 ++- 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index a15caa09bb60..44842c62a3c8 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -2082,6 +2082,7 @@ public class PackageInstaller { /** * Get the value set in {@link SessionParams#setOriginatingUri(Uri)}. + * Note: This value will only be non-null for the owner of the session. */ public @Nullable Uri getOriginatingUri() { return originatingUri; @@ -2096,6 +2097,7 @@ public class PackageInstaller { /** * Get the value set in {@link SessionParams#setReferrerUri(Uri)} + * Note: This value will only be non-null for the owner of the session. */ public @Nullable Uri getReferrerUri() { return referrerUri; diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index d17365db77dd..1c9d56683dba 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -769,26 +769,30 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements public SessionInfo getSessionInfo(int sessionId) { synchronized (mSessions) { final PackageInstallerSession session = mSessions.get(sessionId); - return session != null ? session.generateInfo() : null; + + return session != null + ? session.generateInfoForCaller(true /*withIcon*/, Binder.getCallingUid()) + : null; } } @Override public ParceledListSlice getStagedSessions() { - return mStagingManager.getSessions(); + return mStagingManager.getSessions(Binder.getCallingUid()); } @Override public ParceledListSlice getAllSessions(int userId) { + final int callingUid = Binder.getCallingUid(); mPermissionManager.enforceCrossUserPermission( - Binder.getCallingUid(), userId, true, false, "getAllSessions"); + callingUid, userId, true, false, "getAllSessions"); final List result = new ArrayList<>(); synchronized (mSessions) { for (int i = 0; i < mSessions.size(); i++) { final PackageInstallerSession session = mSessions.valueAt(i); if (session.userId == userId && !session.hasParentSessionId()) { - result.add(session.generateInfo(false)); + result.add(session.generateInfoForCaller(false, callingUid)); } } } @@ -806,7 +810,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements for (int i = 0; i < mSessions.size(); i++) { final PackageInstallerSession session = mSessions.valueAt(i); - SessionInfo info = session.generateInfo(false); + SessionInfo info = + session.generateInfoForCaller(false /*withIcon*/, Process.SYSTEM_UID); if (Objects.equals(info.getInstallerPackageName(), installerPackageName) && session.userId == userId && !session.hasParentSessionId()) { result.add(info); @@ -1250,7 +1255,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements session.markUpdated(); writeSessionsAsync(); if (mOkToSendBroadcasts) { - mPm.sendSessionUpdatedBroadcast(session.generateInfo(false), + // we don't scrub the data here as this is sent only to the installer several + // privileged system packages + mPm.sendSessionUpdatedBroadcast( + session.generateInfoForCaller(false/*icon*/, Process.SYSTEM_UID), session.userId); } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index b661a8553698..1976ffd7a7bf 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -457,11 +457,41 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { stagedSessionErrorMessage != null ? stagedSessionErrorMessage : ""; } - public SessionInfo generateInfo() { - return generateInfo(true); + /** + * Returns {@code true} if the {@link SessionInfo} object should be produced with potentially + * sensitive data scrubbed from its fields. + * + * @param callingUid the uid of the caller; the recipient of the {@link SessionInfo} that may + * need to be scrubbed + */ + private boolean shouldScrubData(int callingUid) { + return !(callingUid < Process.FIRST_APPLICATION_UID || getInstallerUid() == callingUid); + } + + /** + * Generates a {@link SessionInfo} object for the provided uid. This may result in some fields + * that may contain sensitive info being filtered. + * + * @param includeIcon true if the icon should be included in the object + * @param callingUid the uid of the caller; the recipient of the {@link SessionInfo} that may + * need to be scrubbed + * @see #shouldScrubData(int) + */ + public SessionInfo generateInfoForCaller(boolean includeIcon, int callingUid) { + return generateInfoInternal(includeIcon, shouldScrubData(callingUid)); } - public SessionInfo generateInfo(boolean includeIcon) { + /** + * Generates a {@link SessionInfo} object to ensure proper hiding of sensitive fields. + * + * @param includeIcon true if the icon should be included in the object + * @see #generateInfoForCaller(boolean, int) + */ + public SessionInfo generateInfoScrubbed(boolean includeIcon) { + return generateInfoInternal(includeIcon, true /*scrubData*/); + } + + private SessionInfo generateInfoInternal(boolean includeIcon, boolean scrubData) { final SessionInfo info = new SessionInfo(); synchronized (mLock) { info.sessionId = sessionId; @@ -484,9 +514,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { info.appLabel = params.appLabel; info.installLocation = params.installLocation; - info.originatingUri = params.originatingUri; + if (!scrubData) { + info.originatingUri = params.originatingUri; + } info.originatingUid = params.originatingUid; - info.referrerUri = params.referrerUri; + if (!scrubData) { + info.referrerUri = params.referrerUri; + } info.grantedRuntimePermissions = params.grantedRuntimePermissions; info.whitelistedRestrictedPermissions = params.whitelistedRestrictedPermissions; info.installFlags = params.installFlags; @@ -2190,7 +2224,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING); if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts() && (params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) { - mPm.sendSessionCommitBroadcast(generateInfo(), userId); + mPm.sendSessionCommitBroadcast(generateInfoScrubbed(true /*icon*/), userId); } mCallback.onSessionFinished(this, success); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 895d2c5d00bf..dd7133121b21 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -95,11 +95,12 @@ public class StagingManager { } } - ParceledListSlice getSessions() { + ParceledListSlice getSessions(int callingUid) { final List result = new ArrayList<>(); synchronized (mStagedSessions) { for (int i = 0; i < mStagedSessions.size(); i++) { - result.add(mStagedSessions.valueAt(i).generateInfo(false)); + final PackageInstallerSession stagedSession = mStagedSessions.valueAt(i); + result.add(stagedSession.generateInfoForCaller(false /*icon*/, callingUid)); } } return new ParceledListSlice<>(result); -- cgit v1.2.3-59-g8ed1b