Installer package can call performDexOptMode

Test: PlayStore installing itself can trigger dexopt manually
      PlayStore with null installerPackageName cannot trigger
      PlayStore with other installer package name cannot trigger

Change-Id: I9d10951bac84a7c53b9efd89da458982135d3659
This commit is contained in:
Jon Boekenoogen
2022-03-31 21:50:27 -07:00
parent 4da33f636c
commit 7c9923680a
3 changed files with 33 additions and 6 deletions

View File

@@ -446,10 +446,13 @@ final class DexOptHelper {
}
}
public boolean performDexOptMode(String packageName,
public boolean performDexOptMode(@NonNull Computer snapshot, String packageName,
boolean checkProfiles, String targetCompilerFilter, boolean force,
boolean bootComplete, String splitName) {
PackageManagerServiceUtils.enforceSystemOrRootOrShell("performDexOptMode");
if (!PackageManagerServiceUtils.isSystemOrRootOrShell()
&& !isCallerInstallerForPackage(snapshot, packageName)) {
throw new SecurityException("performDexOptMode");
}
int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0)
| (force ? DexoptOptions.DEXOPT_FORCE : 0)
@@ -458,6 +461,22 @@ final class DexOptHelper {
targetCompilerFilter, splitName, flags));
}
private boolean isCallerInstallerForPackage(@NonNull Computer snapshot, String packageName) {
final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
if (packageState == null) {
return false;
}
final InstallSource installSource = packageState.getInstallSource();
final PackageStateInternal installerPackageState =
snapshot.getPackageStateInternal(installSource.installerPackageName);
if (installerPackageState == null) {
return false;
}
final AndroidPackage installerPkg = installerPackageState.getPkg();
return installerPkg.getUid() == Binder.getCallingUid();
}
public boolean performDexOptSecondary(String packageName, String compilerFilter,
boolean force) {
int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX

View File

@@ -972,8 +972,9 @@ public abstract class IPackageManagerBase extends IPackageManager.Stub {
public final boolean performDexOptMode(String packageName,
boolean checkProfiles, String targetCompilerFilter, boolean force,
boolean bootComplete, String splitName) {
return mDexOptHelper.performDexOptMode(packageName, checkProfiles, targetCompilerFilter,
force, bootComplete, splitName);
final Computer snapshot = snapshot();
return mDexOptHelper.performDexOptMode(snapshot, packageName, checkProfiles,
targetCompilerFilter, force, bootComplete, splitName);
}
/**

View File

@@ -1245,12 +1245,19 @@ public class PackageManagerServiceUtils {
* @throws SecurityException if the caller is not system or shell
*/
public static void enforceSystemOrRootOrShell(String message) {
final int uid = Binder.getCallingUid();
if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
if (!isSystemOrRootOrShell()) {
throw new SecurityException(message);
}
}
/**
* Check if the Binder caller is system UID, root's UID, or shell's UID.
*/
public static boolean isSystemOrRootOrShell() {
final int uid = Binder.getCallingUid();
return uid == Process.SYSTEM_UID || uid == Process.ROOT_UID || uid == Process.SHELL_UID;
}
/**
* Check if the Binder caller is system UID or root's UID.
*/