From d2732995bb9542eca713c79385bbe40903d97e57 Mon Sep 17 00:00:00 2001 From: Winson Date: Thu, 27 Feb 2020 14:03:26 -0800 Subject: [PATCH] Skip no-state checkUseInstalled check inside PackageInfoUtils PackageInfoWithoutStateUtils is designed for use in core when the caller doesn't have a PackageSeting. Because its generic generateApplicationInfo method does a simplified checkUseInstalled check without the PackageSetting, this fails whenever state must be taken into account. This introduces method variants which skips the checks and defers to PackageInfoUtils's own check. Bug: 150328400 Test: manual verify call into PackageManager#setSystemAppState with SYSTEM_APP_STATE_UNINSTALLED and verify PackageManager#getApplicationInfo throws NameNotFoundException without fix and succeeds with fix Test: atest com.android.server.pm.parsing Test: TODO PackageInfo(WithoutState)Utils test in follow up change Change-Id: Ie00984c2e1b80d2a3948923dc1293fbfddf01037 --- .../parsing/PackageInfoWithoutStateUtils.java | 89 +++++++++++++++++-- .../server/pm/parsing/PackageInfoUtils.java | 43 ++++----- 2 files changed, 102 insertions(+), 30 deletions(-) diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java index e7d91c205f34e..115d6c42dbf03 100644 --- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java +++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java @@ -40,11 +40,6 @@ import android.content.pm.SELinuxUtil; import android.content.pm.ServiceInfo; import android.content.pm.Signature; import android.content.pm.SigningInfo; -import android.content.pm.parsing.ParsingPackage; -import android.os.Environment; -import android.os.UserHandle; - -import com.android.internal.util.ArrayUtils; import android.content.pm.parsing.component.ComponentParseUtils; import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedComponent; @@ -54,6 +49,10 @@ import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; +import android.os.Environment; +import android.os.UserHandle; + +import com.android.internal.util.ArrayUtils; import libcore.util.EmptyArray; @@ -186,6 +185,22 @@ public class PackageInfoWithoutStateUtils { return null; } + return generateWithoutComponentsUnchecked(pkg, gids, flags, firstInstallTime, + lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo); + } + + /** + * This bypasses critical checks that are necessary for usage with data passed outside of + * system server. + * + * Prefer {@link #generateWithoutComponents(ParsingPackageRead, int[], int, long, long, Set, + * PackageUserState, int, ApexInfo, ApplicationInfo)}. + */ + @NonNull + public static PackageInfo generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids, + @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime, + Set grantedPermissions, PackageUserState state, int userId, + @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) { PackageInfo pi = new PackageInfo(); pi.packageName = pkg.getPackageName(); pi.splitNames = pkg.getSplitNames(); @@ -317,6 +332,18 @@ public class PackageInfoWithoutStateUtils { return null; } + return generateApplicationInfoUnchecked(pkg, flags, state, userId); + } + + /** + * This bypasses critical checks that are necessary for usage with data passed outside of + * system server. + * + * Prefer {@link #generateApplicationInfo(ParsingPackageRead, int, PackageUserState, int)}. + */ + @NonNull + public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg, + @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId) { // Make shallow copy so we can store the metadata/libraries safely ApplicationInfo ai = pkg.toAppInfoWithoutState(); // Init handles data directories @@ -378,6 +405,23 @@ public class PackageInfoWithoutStateUtils { if (applicationInfo == null) { applicationInfo = generateApplicationInfo(pkg, flags, state, userId); } + if (applicationInfo == null) { + return null; + } + + return generateActivityInfoUnchecked(a, applicationInfo); + } + + /** + * This bypasses critical checks that are necessary for usage with data passed outside of + * system server. + * + * Prefer {@link #generateActivityInfo(ParsingPackageRead, ParsedActivity, int, + * PackageUserState, ApplicationInfo, int)}. + */ + @NonNull + public static ActivityInfo generateActivityInfoUnchecked(@NonNull ParsedActivity a, + @NonNull ApplicationInfo applicationInfo) { // Make shallow copies so we can store the metadata safely ActivityInfo ai = new ActivityInfo(); assignSharedFieldsForComponentInfo(ai, a); @@ -431,6 +475,23 @@ public class PackageInfoWithoutStateUtils { if (applicationInfo == null) { applicationInfo = generateApplicationInfo(pkg, flags, state, userId); } + if (applicationInfo == null) { + return null; + } + + return generateServiceInfoUnchecked(s, applicationInfo); + } + + /** + * This bypasses critical checks that are necessary for usage with data passed outside of + * system server. + * + * Prefer {@link #generateServiceInfo(ParsingPackageRead, ParsedService, int, PackageUserState, + * ApplicationInfo, int)}. + */ + @NonNull + public static ServiceInfo generateServiceInfoUnchecked(@NonNull ParsedService s, + @NonNull ApplicationInfo applicationInfo) { // Make shallow copies so we can store the metadata safely ServiceInfo si = new ServiceInfo(); assignSharedFieldsForComponentInfo(si, s); @@ -461,6 +522,24 @@ public class PackageInfoWithoutStateUtils { if (applicationInfo == null) { applicationInfo = generateApplicationInfo(pkg, flags, state, userId); } + if (applicationInfo == null) { + return null; + } + + return generateProviderInfoUnchecked(p, flags, applicationInfo); + } + + /** + * This bypasses critical checks that are necessary for usage with data passed outside of + * system server. + * + * Prefer {@link #generateProviderInfo(ParsingPackageRead, ParsedProvider, int, + * PackageUserState, ApplicationInfo, int)}. + */ + @NonNull + public static ProviderInfo generateProviderInfoUnchecked(@NonNull ParsedProvider p, + @PackageManager.ComponentInfoFlags int flags, + @NonNull ApplicationInfo applicationInfo) { // Make shallow copies so we can store the metadata safely ProviderInfo pi = new ProviderInfo(); assignSharedFieldsForComponentInfo(pi, p); diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index 4ab1f39663d0b..d3f668c5f4d36 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -61,7 +61,6 @@ import libcore.util.EmptyArray; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; @@ -110,12 +109,9 @@ public class PackageInfoUtils { return null; } - PackageInfo info = PackageInfoWithoutStateUtils.generateWithoutComponents(pkg, gids, flags, - firstInstallTime, lastUpdateTime, grantedPermissions, state, userId, apexInfo, - applicationInfo); - if (info == null) { - return null; - } + PackageInfo info = PackageInfoWithoutStateUtils.generateWithoutComponentsUnchecked(pkg, + gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, userId, + apexInfo, applicationInfo); info.isStub = pkg.isStub(); info.coreApp = pkg.isCoreApp(); @@ -220,11 +216,8 @@ public class PackageInfoUtils { return null; } - ApplicationInfo info = PackageInfoWithoutStateUtils.generateApplicationInfo(pkg, flags, - state, userId); - if (info == null) { - return null; - } + ApplicationInfo info = PackageInfoWithoutStateUtils.generateApplicationInfoUnchecked(pkg, + flags, state, userId); if (pkgSetting != null) { // TODO(b/135203078): Remove PackageParser1/toAppInfoWithoutState and clean all this up @@ -267,12 +260,13 @@ public class PackageInfoUtils { if (applicationInfo == null) { applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); } - ActivityInfo info = PackageInfoWithoutStateUtils.generateActivityInfo(pkg, a, flags, state, - applicationInfo, userId); - if (info == null) { + + if (applicationInfo == null) { return null; } + ActivityInfo info = + PackageInfoWithoutStateUtils.generateActivityInfoUnchecked(a, applicationInfo); assignSharedFieldsForComponentInfo(info, a, pkgSetting); return info; } @@ -302,12 +296,12 @@ public class PackageInfoUtils { if (applicationInfo == null) { applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); } - ServiceInfo info = PackageInfoWithoutStateUtils.generateServiceInfo(pkg, s, flags, state, - applicationInfo, userId); - if (info == null) { + if (applicationInfo == null) { return null; } + ServiceInfo info = + PackageInfoWithoutStateUtils.generateServiceInfoUnchecked(s, applicationInfo); assignSharedFieldsForComponentInfo(info, s, pkgSetting); return info; } @@ -321,21 +315,20 @@ public class PackageInfoUtils { @NonNull ApplicationInfo applicationInfo, int userId, @Nullable PackageSetting pkgSetting) { if (p == null) return null; + if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { + return null; + } if (applicationInfo == null || !pkg.getPackageName().equals(applicationInfo.packageName)) { Slog.wtf(TAG, "AppInfo's package name is different. Expected=" + pkg.getPackageName() + " actual=" + (applicationInfo == null ? "(null AppInfo)" : applicationInfo.packageName)); applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); } - if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { + if (applicationInfo == null) { return null; } - ProviderInfo info = PackageInfoWithoutStateUtils.generateProviderInfo(pkg, p, flags, state, - applicationInfo, userId); - if (info == null) { - return null; - } - + ProviderInfo info = PackageInfoWithoutStateUtils.generateProviderInfoUnchecked(p, flags, + applicationInfo); assignSharedFieldsForComponentInfo(info, p, pkgSetting); return info; }