From f958fee253fca7524ece7423a5769fe99081272f Mon Sep 17 00:00:00 2001 From: Jackal Guo Date: Thu, 10 Dec 2020 09:54:54 +0800 Subject: [PATCH] Fix system server crash during movePackage After reducing package parsing times, we use cached PackageLite instead of parsing on demand. Therefore, this cached PackageLite shouldn't be null in normal case. Since movePackage flow doesn't have a valid PackageLite, the NPE results in system server crash. Parse and cache PackageLite for movePackage case, and add null check to avoid the crash. Bug: 175148169 Test: atest AdoptableHostTest Change-Id: I3e54adc2f3b5f87ea6a6f3109aa138f3c93dcfd2 --- .../android/server/pm/PackageManagerService.java | 13 ++++++++++--- .../server/pm/PackageManagerServiceUtils.java | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index a123f369a9abf..cd5ea5eef8624 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -238,6 +238,7 @@ import android.content.pm.VersionedPackage; import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; import android.content.pm.dex.IArtManager; +import android.content.pm.parsing.ApkLiteParseUtils; import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedInstrumentation; @@ -248,6 +249,8 @@ import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; +import android.content.pm.parsing.result.ParseResult; +import android.content.pm.parsing.result.ParseTypeImpl; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; @@ -15316,7 +15319,7 @@ public class PackageManagerService extends IPackageManager.Stub InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, - UserHandle user, String packageAbiOverride) { + UserHandle user, String packageAbiOverride, PackageLite packageLite) { super(user); this.origin = origin; this.move = move; @@ -15334,7 +15337,7 @@ public class PackageManagerService extends IPackageManager.Stub this.forceQueryableOverride = false; this.mDataLoaderType = DataLoaderType.NONE; this.requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST; - this.mPackageLite = null; + this.mPackageLite = packageLite; } InstallParams(File stagedDir, IPackageInstallObserver2 observer, @@ -24156,8 +24159,12 @@ public class PackageManagerService extends IPackageManager.Stub final Message msg = mHandler.obtainMessage(INIT_COPY); final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); + final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); + final ParseResult ret = ApkLiteParseUtils.parsePackageLite(input, + new File(origin.resolvedPath), /* flags */ 0); + final PackageLite lite = ret.isSuccess() ? ret.getResult() : null; final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, - installSource, volumeUuid, user, packageAbiOverride); + installSource, volumeUuid, user, packageAbiOverride, lite); params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); msg.obj = params; diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java index c77eda161c678..d3d7c6055fcec 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java @@ -822,7 +822,7 @@ public class PackageManagerServiceUtils { public static PackageInfoLite getMinimalPackageInfo(Context context, PackageParser.PackageLite pkg, String packagePath, int flags, String abiOverride) { final PackageInfoLite ret = new PackageInfoLite(); - if (packagePath == null) { + if (packagePath == null || pkg == null) { Slog.i(TAG, "Invalid package file " + packagePath); ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK; return ret;