diff options
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 10 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/InstallPackageHelper.java | 24 |
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) { |