From 4925e3a22097214728dedbd4375ff54f8a1a9541 Mon Sep 17 00:00:00 2001 From: Alex Buynytskyy Date: Wed, 1 Jul 2020 12:28:47 -0700 Subject: [PATCH] Fix transfer API. Transfer API should throw security exception when transfering the session which is not installing the original installer. Moving it onto commit stage and still fail the installation. Fixes: 158805288 Test: atest InstallSessionTransferTest Test: atest -p frameworks/base/services/core/java/com/android/server/pm Change-Id: I8511d4357788e70f83bcbd366908b42a691afbcb --- .../android/content/pm/PackageInstaller.java | 5 ++--- .../server/pm/PackageInstallerSession.java | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index c2ae7f12df965..df9db278e095e 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1292,9 +1292,8 @@ public class PackageInstaller { * * @throws PackageManager.NameNotFoundException if the new owner could not be found. * @throws SecurityException if called after the session has been committed or abandoned. - * @throws SecurityException if the session does not update the original installer - * @throws SecurityException if streams opened through - * {@link #openWrite(String, long, long) are still open. + * @throws IllegalArgumentException if streams opened through + * {@link #openWrite(String, long, long) are still open. */ public void transfer(@NonNull String packageName) throws PackageManager.NameNotFoundException { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index cceec3ab373f5..5f488711ceb16 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -268,6 +268,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /** Uid of the creator of this session. */ private final int mOriginalInstallerUid; + /** Package name of the app that created the installation session. */ + private final String mOriginalInstallerPackageName; + /** Uid of the owner of the installer session */ @GuardedBy("mLock") private int mInstallerUid; @@ -557,6 +560,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mOriginalInstallerUid = installerUid; mInstallerUid = installerUid; mInstallSource = Objects.requireNonNull(installSource); + mOriginalInstallerPackageName = mInstallSource.installerPackageName; this.params = params; this.createdMillis = createdMillis; this.updatedMillis = createdMillis; @@ -1662,11 +1666,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new IllegalArgumentException("Package is not valid", e); } - if (!mPackageName.equals(mInstallSource.installerPackageName)) { - throw new SecurityException("Can only transfer sessions that update the original " - + "installer"); - } - mInstallerUid = newOwnerAppInfo.uid; mInstallSource = InstallSource.create(packageName, null, packageName, null); } @@ -2183,6 +2182,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Incremental installation of this package is not allowed."); } + if (mInstallerUid != mOriginalInstallerUid) { + // Session has been transferred, check package name. + if (TextUtils.isEmpty(mPackageName) || !mPackageName.equals( + mOriginalInstallerPackageName)) { + throw new PackageManagerException(PackageManager.INSTALL_FAILED_PACKAGE_CHANGED, + "Can only transfer sessions that update the original installer"); + } + } + if (params.mode == SessionParams.MODE_FULL_INSTALL) { // Full installs must include a base package if (!stagedSplits.contains(null)) { @@ -3212,6 +3220,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { pw.printPair("userId", userId); pw.printPair("mOriginalInstallerUid", mOriginalInstallerUid); + pw.printPair("mOriginalInstallerPackageName", mOriginalInstallerPackageName); pw.printPair("installerPackageName", mInstallSource.installerPackageName); pw.printPair("installInitiatingPackageName", mInstallSource.initiatingPackageName); pw.printPair("installOriginatingPackageName", mInstallSource.originatingPackageName);