From 929ab61a147bc1866fed7a8d01a4e8f6affa39ac Mon Sep 17 00:00:00 2001 From: Patrick Baumann Date: Fri, 6 Mar 2020 10:34:17 -0800 Subject: [PATCH] RESTRICT AUTOMERGE 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: Manual via test app in related bug Change-Id: I84679ea0636aa2097e25e23813c48134c9cc1d75 --- .../android/content/pm/PackageInstaller.java | 2 + .../server/pm/PackageInstallerService.java | 13 ++++-- .../server/pm/PackageInstallerSession.java | 46 ++++++++++++++++--- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 5673361420cc5..fa455fff31415 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1571,6 +1571,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; @@ -1585,6 +1586,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 49bf8cc830abf..4c1bcd9275492 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -683,20 +683,24 @@ public class PackageInstallerService extends IPackageInstaller.Stub { 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 getAllSessions(int userId) { - mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getAllSessions"); + final int callingUid = Binder.getCallingUid(); + mPm.enforceCrossUserPermission(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) { - result.add(session.generateInfo(false)); + result.add(session.generateInfoForCaller(false, callingUid)); } } } @@ -713,7 +717,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { 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) { result.add(info); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 3f1c8a136307c..c392ab8c704e5 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -386,11 +386,41 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } - 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); } - public SessionInfo generateInfo(boolean includeIcon) { + /** + * 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)); + } + + /** + * 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; @@ -411,9 +441,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.installFlags = params.installFlags; } @@ -1490,7 +1524,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Send broadcast to default launcher only if it's a new install final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING); if (success && isNewInstall) { - mPm.sendSessionCommitBroadcast(generateInfo(), userId); + mPm.sendSessionCommitBroadcast(generateInfoScrubbed(true /*icon*/), userId); } mCallback.onSessionFinished(this, success);