summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageManager.java10
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java24
2 files changed, 34 insertions, 0 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 485d04db82d5..88b5e021882a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1959,6 +1959,14 @@ public abstract class PackageManager {
public static final int INSTALL_FAILED_MISSING_SPLIT = -28;
/**
+ * Installation return code: this is passed in the {@link PackageInstaller#EXTRA_LEGACY_STATUS}
+ * if the new package targets a deprecated SDK version.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FAILED_DEPRECATED_SDK_VERSION = -29;
+
+ /**
* Installation parse return code: this is passed in the
* {@link PackageInstaller#EXTRA_LEGACY_STATUS} if the parser was given a path that is not a
* file, or does not end with the expected '.apk' extension.
@@ -9618,6 +9626,7 @@ public abstract class PackageManager {
case INSTALL_FAILED_ABORTED: return "INSTALL_FAILED_ABORTED";
case INSTALL_FAILED_BAD_DEX_METADATA: return "INSTALL_FAILED_BAD_DEX_METADATA";
case INSTALL_FAILED_MISSING_SPLIT: return "INSTALL_FAILED_MISSING_SPLIT";
+ case INSTALL_FAILED_DEPRECATED_SDK_VERSION: return "INSTALL_FAILED_DEPRECATED_SDK_VERSION";
case INSTALL_FAILED_BAD_SIGNATURE: return "INSTALL_FAILED_BAD_SIGNATURE";
case INSTALL_FAILED_WRONG_INSTALLED_VERSION: return "INSTALL_FAILED_WRONG_INSTALLED_VERSION";
case INSTALL_FAILED_PROCESS_NOT_DEFINED: return "INSTALL_FAILED_PROCESS_NOT_DEFINED";
@@ -9675,6 +9684,7 @@ public abstract class PackageManager {
case INSTALL_FAILED_ABORTED: return PackageInstaller.STATUS_FAILURE_ABORTED;
case INSTALL_FAILED_MISSING_SPLIT: return PackageInstaller.STATUS_FAILURE_INCOMPATIBLE;
case INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE: return PackageInstaller.STATUS_FAILURE_BLOCKED;
+ case INSTALL_FAILED_DEPRECATED_SDK_VERSION: return PackageInstaller.STATUS_FAILURE_INCOMPATIBLE;
default: return PackageInstaller.STATUS_FAILURE;
}
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 5dd5d81cfbb6..e8db10d792be 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_PERMISSION_GROUP;
+import static android.content.pm.PackageManager.INSTALL_FAILED_DEPRECATED_SDK_VERSION;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP;
@@ -136,6 +137,7 @@ import android.os.incremental.IncrementalManager;
import android.os.incremental.IncrementalStorage;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
+import android.provider.DeviceConfig;
import android.stats.storage.StorageEnums;
import android.system.ErrnoException;
import android.system.Os;
@@ -1017,6 +1019,28 @@ final class InstallPackageHelper {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
+ // If the minimum installable SDK version enforcement is enabled, block the install
+ // of apps using a lower target SDK version than required. This helps improve security
+ // and privacy as malware can target older SDK versions to avoid enforcement of new API
+ // behavior.
+ if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ "MinInstallableTargetSdk__install_block_enabled",
+ false)) {
+ int minInstallableTargetSdk =
+ DeviceConfig.getInt(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ "MinInstallableTargetSdk__min_installable_target_sdk",
+ 0);
+ if (parsedPackage.getTargetSdkVersion() < minInstallableTargetSdk) {
+ Slog.w(TAG, "App " + parsedPackage.getPackageName()
+ + " targets deprecated sdk version");
+ throw new PrepareFailure(INSTALL_FAILED_DEPRECATED_SDK_VERSION,
+ "App package must target at least version "
+ + minInstallableTargetSdk);
+ }
+ } else {
+ Slog.i(TAG, "Minimum installable target sdk enforcement not enabled");
+ }
+
// Instant apps have several additional install-time checks.
if (instantApp) {
if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {