From 66ed8dff3796a3eb4a692dd8727f69ca3cd492a1 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Wed, 25 Mar 2020 08:59:34 -0700 Subject: [PATCH] Define permission for installer API v2 The package installer v2 APIs were marked as @SystemApi merely as a convenience for development. These APIs may change in the next version of Android and their usage must be strictly controlled. Bug: 151716357 Test: Manual. Use old Shell and see that incremental installation fails with a SecurityException Test: Manual. Request INSTALLER_V2 permission for shell and see that incremental installation succeeds Change-Id: I9612dc145eadda20083bcc43e7a35ef3cd90aa40 --- api/system-current.txt | 8 ++++---- core/java/android/content/pm/PackageInstaller.java | 7 ++++++- core/res/AndroidManifest.xml | 10 ++++++++++ packages/Shell/AndroidManifest.xml | 2 ++ .../com/android/server/pm/PackageInstallerService.java | 8 ++++++++ .../com/android/server/pm/PackageInstallerSession.java | 3 +++ 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index 50900aa3e6970..4b6d636e799d8 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2107,10 +2107,10 @@ package android.content.pm { } public static class PackageInstaller.Session implements java.io.Closeable { - method public void addFile(int, @NonNull String, long, @NonNull byte[], @Nullable byte[]); + method @RequiresPermission("com.android.permission.USE_INSTALLER_V2") public void addFile(int, @NonNull String, long, @NonNull byte[], @Nullable byte[]); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void commitTransferred(@NonNull android.content.IntentSender); - method @Nullable public android.content.pm.DataLoaderParams getDataLoaderParams(); - method public void removeFile(int, @NonNull String); + method @Nullable @RequiresPermission("com.android.permission.USE_INSTALLER_V2") public android.content.pm.DataLoaderParams getDataLoaderParams(); + method @RequiresPermission("com.android.permission.USE_INSTALLER_V2") public void removeFile(int, @NonNull String); } public static class PackageInstaller.SessionInfo implements android.os.Parcelable { @@ -2131,7 +2131,7 @@ package android.content.pm { public static class PackageInstaller.SessionParams implements android.os.Parcelable { method @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE) public void setAllocateAggressive(boolean); method @Deprecated public void setAllowDowngrade(boolean); - method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setDataLoaderParams(@NonNull android.content.pm.DataLoaderParams); + method @RequiresPermission(allOf={android.Manifest.permission.INSTALL_PACKAGES, "com.android.permission.USE_INSTALLER_V2"}) public void setDataLoaderParams(@NonNull android.content.pm.DataLoaderParams); method public void setDontKillApp(boolean); method public void setEnableRollback(boolean); method public void setEnableRollback(boolean, int); diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 50bee854c0274..1e0b2e358e175 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1118,6 +1118,7 @@ public class PackageInstaller { * {@hide} */ @SystemApi + @RequiresPermission(android.Manifest.permission.USE_INSTALLER_V2) public @Nullable DataLoaderParams getDataLoaderParams() { try { DataLoaderParamsParcel data = mSession.getDataLoaderParams(); @@ -1157,6 +1158,7 @@ public class PackageInstaller { * {@hide} */ @SystemApi + @RequiresPermission(android.Manifest.permission.USE_INSTALLER_V2) public void addFile(@FileLocation int location, @NonNull String name, long lengthBytes, @NonNull byte[] metadata, @Nullable byte[] signature) { try { @@ -1180,6 +1182,7 @@ public class PackageInstaller { * {@hide} */ @SystemApi + @RequiresPermission(android.Manifest.permission.USE_INSTALLER_V2) public void removeFile(@FileLocation int location, @NonNull String name) { try { mSession.removeFile(location, name); @@ -1927,7 +1930,9 @@ public class PackageInstaller { * {@hide} */ @SystemApi - @RequiresPermission(Manifest.permission.INSTALL_PACKAGES) + @RequiresPermission(allOf = { + Manifest.permission.INSTALL_PACKAGES, + Manifest.permission.USE_INSTALLER_V2}) public void setDataLoaderParams(@NonNull DataLoaderParams dataLoaderParams) { this.dataLoaderParams = dataLoaderParams; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 68c51b9a7811f..b1d456acb67be 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3641,6 +3641,16 @@ + + + + diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 2ff3d2a3a9385..8ff7ea9d61dd2 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -490,6 +490,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements throw new SecurityException("User restriction prevents installing"); } + if (params.dataLoaderParams != null + && mContext.checkCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("You need the " + + "com.android.permission.USE_INSTALLER_V2 permission " + + "to use a data loader"); + } + String requestedInstallerPackageName = params.installerPackageName != null ? params.installerPackageName : installerPackageName; diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 348a4cb771639..42ed20654a2cb 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2479,12 +2479,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public DataLoaderParamsParcel getDataLoaderParams() { + mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null); return params.dataLoaderParams != null ? params.dataLoaderParams.getData() : null; } @Override public void addFile(int location, String name, long lengthBytes, byte[] metadata, byte[] signature) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null); if (!isDataLoaderInstallation()) { throw new IllegalStateException( "Cannot add files to non-data loader installation session."); @@ -2517,6 +2519,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void removeFile(int location, String name) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null); if (!isDataLoaderInstallation()) { throw new IllegalStateException( "Cannot add files to non-data loader installation session.");