1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.UserIdInt; 23 import android.content.pm.PackageManager; 24 import android.content.pm.PackageManagerInternal; 25 import android.content.res.Resources; 26 import android.os.SystemProperties; 27 import android.os.UserHandle; 28 import android.util.ArrayMap; 29 import android.util.ArraySet; 30 import android.util.DebugUtils; 31 import android.util.IndentingPrintWriter; 32 import android.util.Slog; 33 import android.util.SparseArrayMap; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 import com.android.server.LocalServices; 37 import com.android.server.SystemConfig; 38 import com.android.server.pm.pkg.AndroidPackage; 39 import com.android.server.pm.pkg.PackageStateInternal; 40 41 import java.lang.annotation.Retention; 42 import java.lang.annotation.RetentionPolicy; 43 import java.util.ArrayList; 44 import java.util.Arrays; 45 import java.util.Collections; 46 import java.util.List; 47 import java.util.Map; 48 import java.util.Set; 49 50 /** 51 * Responsible for un/installing system packages based on user type. 52 * 53 * <p>Uses the SystemConfig's install-in-user-type allowlist; 54 * see {@link SystemConfig#getAndClearPackageToUserTypeWhitelist} and 55 * {@link SystemConfig#getAndClearPackageToUserTypeBlacklist}. 56 * 57 * <p>If {@link #isEnforceMode()} is false, then all system packages are always installed for all 58 * users. The following applies when it is true. 59 * 60 * <p>Any package can be in one of three states in the {@code SystemConfig} allowlist 61 * <ol> 62 * <li>Explicitly denylisted for a particular user type</li> 63 * <li>Explicitly allowlisted for a particular user type</li> 64 * <li>Not mentioned at all, for any user type (neither allowlisted nor denylisted)</li> 65 * </ol> 66 * 67 * <p>Denylisting always takes precedence - if a package is denylisted for a particular user, 68 * it won't be installed on that type of user (even if it is also allowlisted for that user). 69 * Next comes allowlisting - if it is allowlisted for a particular user, it will be installed on 70 * that type of user (as long as it isn't denylisted). 71 * Finally, if the package is not mentioned at all (i.e. neither allowlisted nor denylisted for 72 * any user types) in the SystemConfig 'install-in-user-type' lists 73 * then: 74 * <ul> 75 * <li>If {@link #isImplicitWhitelistMode()}, the package is implicitly treated as allowlisted 76 * for <b>all</b> users</li> 77 * <li>Otherwise, if {@link #isImplicitWhitelistSystemMode()}, the package is implicitly treated 78 * as allowlisted for the <b>{@link UserHandle#USER_SYSTEM}</b> user (not other users), 79 * which is useful for local development purposes</li> 80 * <li>Otherwise, the package is implicitly treated as denylisted for all users</li> 81 * </ul> 82 * 83 * <p>Packages are only installed/uninstalled by this mechanism when a new user is created or during 84 * an update. In the case of updates:<ul> 85 * <li>new packages are (un)installed per the allowlist/denylist</li> 86 * <li>pre-existing installed denylisted packages are never uninstalled</li> 87 * <li>pre-existing not-installed allowlisted packages are only installed if the reason why they 88 * had been previously uninstalled was due to UserSystemPackageInstaller</li> 89 * </ul> 90 * 91 * <p><b>NOTE:</b> the {@code SystemConfig} state is only updated on first boot or after a system 92 * update. So, to verify changes during development, you can emulate the latter by calling: 93 * <pre><code> 94 * adb shell setprop persist.pm.mock-upgrade true 95 * </code></pre> 96 */ 97 class UserSystemPackageInstaller { 98 private static final String TAG = UserSystemPackageInstaller.class.getSimpleName(); 99 100 private static final boolean DEBUG = false; 101 102 /** 103 * System Property whether to only install system packages on a user if they're allowlisted for 104 * that user type. These are flags and can be freely combined. 105 * <ul> 106 * <li> 0 - disable allowlist (install all system packages; no logging)</li> 107 * <li> 1 - enforce (only install system packages if they are allowlisted)</li> 108 * <li> 2 - log (log non-allowlisted packages)</li> 109 * <li> 4 - for all users: implicitly allowlist any package not mentioned in the allowlist</li> 110 * <li> 8 - for SYSTEM: implicitly allowlist any package not mentioned in the allowlist</li> 111 * <li> 16 - ignore OTAs (don't install system packages during OTAs)</li> 112 * <li>-1 - use device default (as defined in res/res/values/config.xml)</li> 113 * </ul> 114 * Note: This list must be kept current with config_userTypePackageWhitelistMode in 115 * frameworks/base/core/res/res/values/config.xml 116 */ 117 static final String PACKAGE_WHITELIST_MODE_PROP = "persist.debug.user.package_whitelist_mode"; 118 119 // NOTE: flags below are public so they can used by DebugUtils.flagsToString. And this class 120 // itself is package-protected, so it doesn't matter... 121 public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0x00; 122 public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0x01; 123 public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_LOG = 0x02; 124 public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0x04; 125 public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM = 0x08; 126 public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA = 0x10; 127 static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT = -1; 128 129 // Used by Shell command only 130 static final int USER_TYPE_PACKAGE_WHITELIST_MODE_NONE = -1000; 131 132 @IntDef(flag = true, prefix = "USER_TYPE_PACKAGE_WHITELIST_MODE_", value = { 133 USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE, 134 USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE, 135 USER_TYPE_PACKAGE_WHITELIST_MODE_LOG, 136 USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST, 137 USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA, 138 }) 139 @Retention(RetentionPolicy.SOURCE) 140 public @interface PackageWhitelistMode {} 141 142 /** 143 * Maps system package manifest names to a bitset representing (via {@link #getUserTypeMask}) 144 * the user types on which they should be initially installed. 145 * <p> 146 * E.g. if package "pkg1" should be installed on "usertype_d", which is the user type for which 147 * {@link #getUserTypeMask}("usertype_d") returns (1 << 3) 148 * then mWhitelistedPackagesForUserTypes.get("pkg1") will be a Long whose 149 * bit in position 3 will equal 1. 150 * <p> 151 * Packages that are allowlisted, but then denylisted so that they aren't to be installed on 152 * any user, are purposefully still present in this list. 153 */ 154 private final ArrayMap<String, Long> mWhitelistedPackagesForUserTypes; 155 156 private final UserManagerService mUm; 157 158 /** 159 * Alphabetically sorted list of user types. 160 * Throughout this class, a long (functioning as a bitset) has its ith bit representing 161 * the user type stored in mUserTypes[i]. 162 * mUserTypes cannot exceed Long.SIZE (since we are using long for our bitset). 163 */ 164 private final String[] mUserTypes; 165 UserSystemPackageInstaller(UserManagerService um, ArrayMap<String, UserTypeDetails> userTypes)166 UserSystemPackageInstaller(UserManagerService um, ArrayMap<String, UserTypeDetails> userTypes) { 167 mUm = um; 168 mUserTypes = getAndSortKeysFromMap(userTypes); 169 if (mUserTypes.length > Long.SIZE) { 170 throw new IllegalArgumentException("Device contains " + userTypes.size() 171 + " user types. However, UserSystemPackageInstaller does not work if there are" 172 + " more than " + Long.SIZE + " user types."); 173 // UserSystemPackageInstaller could use a BitSet instead of Long in this case. 174 // But, currently, 64 user types is far beyond expectations, so we have not done so. 175 } 176 mWhitelistedPackagesForUserTypes = 177 determineWhitelistedPackagesForUserTypes(SystemConfig.getInstance()); 178 } 179 180 /** Constructor for testing purposes. */ 181 @VisibleForTesting UserSystemPackageInstaller(UserManagerService ums, ArrayMap<String, Long> whitelist, String[] sortedUserTypes)182 UserSystemPackageInstaller(UserManagerService ums, ArrayMap<String, Long> whitelist, 183 String[] sortedUserTypes) { 184 mUm = ums; 185 mUserTypes = sortedUserTypes; 186 mWhitelistedPackagesForUserTypes = whitelist; 187 } 188 189 /** 190 * During OTAs and first boot, install/uninstall all system packages for all users based on the 191 * user's user type and the SystemConfig allowlist. 192 * We do NOT uninstall packages during an OTA though. 193 * 194 * This is responsible for enforcing the allowlist for pre-existing users (i.e. USER_SYSTEM); 195 * enforcement for new users is done when they are created in UserManagerService.createUser(). 196 * 197 * @param preExistingPackages list of packages on the device prior to the upgrade. Cannot be 198 * null if isUpgrade is true. 199 */ installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade, @Nullable ArraySet<String> preExistingPackages)200 boolean installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade, 201 @Nullable ArraySet<String> preExistingPackages) { 202 final int mode = getWhitelistMode(); 203 checkWhitelistedSystemPackages(mode); 204 final boolean isConsideredUpgrade = isUpgrade && !isIgnoreOtaMode(mode); 205 if (!isConsideredUpgrade && !isFirstBoot) { 206 return false; 207 } 208 if (isFirstBoot && !isEnforceMode(mode)) { 209 // Note that if !isEnforceMode, we nonetheless still install packages if isUpgrade 210 // in order to undo any previous non-installing. isFirstBoot lacks this requirement. 211 return false; 212 } 213 Slog.i(TAG, "Reviewing whitelisted packages due to " 214 + (isFirstBoot ? "[firstBoot]" : "") + (isConsideredUpgrade ? "[upgrade]" : "")); 215 final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); 216 217 // User ID -> package name -> installed 218 SparseArrayMap<String, Boolean> changesToCommit = new SparseArrayMap<>(); 219 220 // Install/uninstall system packages per user. 221 for (int userId : mUm.getUserIds()) { 222 final Set<String> userAllowlist = getInstallablePackagesForUserId(userId); 223 224 pmInt.forEachPackageState(packageState -> { 225 if (packageState.getPkg() == null || !packageState.isSystem()) { 226 return; 227 } 228 boolean install = (userAllowlist == null 229 || userAllowlist.contains(packageState.getPackageName())) 230 && !packageState.getTransientState().isHiddenUntilInstalled(); 231 if (packageState.getUserStateOrDefault(userId).isInstalled() != install 232 && shouldChangeInstallationState(packageState, install, userId, 233 isFirstBoot, isConsideredUpgrade, preExistingPackages)) { 234 changesToCommit.add(userId, packageState.getPackageName(), install); 235 } 236 }); 237 } 238 239 pmInt.commitPackageStateMutation(null, packageStateMutator -> { 240 for (int userIndex = 0; userIndex < changesToCommit.numMaps(); userIndex++) { 241 int userId = changesToCommit.keyAt(userIndex); 242 int packagesSize = changesToCommit.numElementsForKey(userId); 243 for (int packageIndex = 0; packageIndex < packagesSize; ++packageIndex) { 244 String packageName = changesToCommit.keyAt(userIndex, packageIndex); 245 boolean installed = changesToCommit.valueAt(userIndex, packageIndex); 246 packageStateMutator.forPackage(packageName) 247 .userState(userId) 248 .setInstalled(installed) 249 .setUninstallReason(installed 250 ? PackageManager.UNINSTALL_REASON_UNKNOWN 251 : PackageManager.UNINSTALL_REASON_USER_TYPE); 252 253 Slog.i(TAG + "CommitDebug", (installed ? "Installed " : "Uninstalled ") 254 + packageName + " for user " + userId); 255 } 256 } 257 }); 258 259 return true; 260 } 261 262 /** 263 * Returns whether to proceed with install/uninstall for the given package. 264 * In particular, do not install a package unless it was only uninstalled due to the user type; 265 * and do not uninstall a package if it previously was installed (prior to the OTA). 266 * 267 * Should be called only within PackageManagerInternal.forEachPackageSetting() since it 268 * requires the LP lock. 269 * 270 * @param preOtaPkgs list of packages on the device prior to the upgrade. 271 * Cannot be null if isUpgrade is true. 272 */ shouldChangeInstallationState(PackageStateInternal packageState, boolean install, @UserIdInt int userId, boolean isFirstBoot, boolean isUpgrade, @Nullable ArraySet<String> preOtaPkgs)273 private static boolean shouldChangeInstallationState(PackageStateInternal packageState, 274 boolean install, 275 @UserIdInt int userId, 276 boolean isFirstBoot, 277 boolean isUpgrade, 278 @Nullable ArraySet<String> preOtaPkgs) { 279 if (install) { 280 // Only proceed with install if we are the only reason why it had been uninstalled. 281 return packageState.getUserStateOrDefault(userId).getUninstallReason() 282 == PackageManager.UNINSTALL_REASON_USER_TYPE; 283 } else { 284 // Only proceed with uninstall if the package is new to the device. 285 return isFirstBoot 286 || (isUpgrade && !preOtaPkgs.contains(packageState.getPackageName())); 287 } 288 } 289 290 /** 291 * Checks whether the system packages and the mWhitelistedPackagesForUserTypes allowlist are 292 * in 1-to-1 correspondence. 293 */ checkWhitelistedSystemPackages(@ackageWhitelistMode int mode)294 private void checkWhitelistedSystemPackages(@PackageWhitelistMode int mode) { 295 if (!isLogMode(mode) && !isEnforceMode(mode)) { 296 return; 297 } 298 Slog.v(TAG, "Checking that all system packages are whitelisted."); 299 300 // Check whether all allowlisted packages are indeed on the system. 301 final List<String> warnings = getPackagesWhitelistWarnings(); 302 final int numberWarnings = warnings.size(); 303 if (numberWarnings == 0) { 304 Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) 305 + ") has no warnings"); 306 } else { 307 Slog.w(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) 308 + ") has " + numberWarnings + " warnings:"); 309 for (int i = 0; i < numberWarnings; i++) { 310 Slog.w(TAG, warnings.get(i)); 311 } 312 } 313 314 // Check whether all system packages are indeed allowlisted. 315 if (isImplicitWhitelistMode(mode) && !isLogMode(mode)) { 316 return; 317 } 318 319 final List<String> errors = getPackagesWhitelistErrors(mode); 320 final int numberErrors = errors.size(); 321 322 if (numberErrors == 0) { 323 Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) 324 + ") has no errors"); 325 return; 326 } 327 Slog.e(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has " 328 + numberErrors + " errors:"); 329 330 boolean doWtf = !isImplicitWhitelistMode(mode); 331 for (int i = 0; i < numberErrors; i++) { 332 final String msg = errors.get(i); 333 if (doWtf) { 334 Slog.wtf(TAG, msg); 335 } else { 336 Slog.e(TAG, msg); 337 } 338 } 339 } 340 341 /** 342 * Gets packages that are listed in the allowlist XML but are not present on the system image. 343 */ 344 @NonNull getPackagesWhitelistWarnings()345 private List<String> getPackagesWhitelistWarnings() { 346 final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages(); 347 final List<String> warnings = new ArrayList<>(); 348 final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); 349 350 // Check whether all allowlisted packages are indeed on the system. 351 final String notPresentFmt = "%s is allowlisted but not present."; 352 final String notSystemFmt = "%s is allowlisted and present but not a system package."; 353 final String overlayFmt = "%s is allowlisted unnecessarily since it's a static overlay."; 354 for (String pkgName : allWhitelistedPackages) { 355 var packageState = pmInt.getPackageStateInternal(pkgName); 356 var pkg = packageState == null ? null : packageState.getAndroidPackage(); 357 if (pkg == null) { 358 warnings.add(String.format(notPresentFmt, pkgName)); 359 } else if (!packageState.isSystem()) { 360 warnings.add(String.format(notSystemFmt, pkgName)); 361 } else if (shouldUseOverlayTargetName(pkg)) { 362 warnings.add(String.format(overlayFmt, pkgName)); 363 } 364 } 365 return warnings; 366 } 367 368 /** 369 * Gets packages that are not listed in the allowlist XMLs when they should be. 370 */ 371 @NonNull getPackagesWhitelistErrors(@ackageWhitelistMode int mode)372 private List<String> getPackagesWhitelistErrors(@PackageWhitelistMode int mode) { 373 if ((!isEnforceMode(mode) || isImplicitWhitelistMode(mode)) && !isLogMode(mode)) { 374 return Collections.emptyList(); 375 } 376 377 final List<String> errors = new ArrayList<>(); 378 final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages(); 379 final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); 380 381 // Check whether all system packages are indeed allowlisted. 382 final String logMessageFmt = "System package %s is not whitelisted using " 383 + "'install-in-user-type' in SystemConfig for any user types!"; 384 pmInt.forEachPackageState(packageState -> { 385 var pkg = packageState.getAndroidPackage(); 386 if (pkg == null || !packageState.isSystem() || pkg.isApex()) return; 387 final String pkgName = pkg.getManifestPackageName(); 388 if (!allWhitelistedPackages.contains(pkgName) 389 && !shouldUseOverlayTargetName(pmInt.getPackage(pkgName))) { 390 errors.add(String.format(logMessageFmt, pkgName)); 391 } 392 }); 393 394 return errors; 395 } 396 397 /** Whether to only install system packages in new users for which they are allowlisted. */ isEnforceMode()398 boolean isEnforceMode() { 399 return isEnforceMode(getWhitelistMode()); 400 } 401 402 /** 403 * Whether to ignore OTAs, and therefore not install missing system packages during OTAs. 404 * <p>Note: 405 * If in this mode, old system packages will not be installed on pre-existing users during OTAs. 406 * Any system packages that had not been installed at the time of the user's creation, 407 * due to {@link UserSystemPackageInstaller}'s previous actions, will therefore continue to 408 * remain uninstalled, even if the allowlist (or enforcement mode) now declares that they should 409 * be. 410 */ isIgnoreOtaMode()411 boolean isIgnoreOtaMode() { 412 return isIgnoreOtaMode(getWhitelistMode()); 413 } 414 415 /** 416 * Whether to log a warning concerning potential problems with the user-type package allowlist. 417 */ isLogMode()418 boolean isLogMode() { 419 return isLogMode(getWhitelistMode()); 420 } 421 422 /** 423 * Whether to treat all packages that are not mentioned at all in the allowlist to be implicitly 424 * allowlisted for all users. 425 */ isImplicitWhitelistMode()426 boolean isImplicitWhitelistMode() { 427 return isImplicitWhitelistMode(getWhitelistMode()); 428 } 429 430 /** 431 * Whether to treat all packages that are not mentioned at all in the allowlist to be implicitly 432 * allowlisted for the SYSTEM user. 433 */ isImplicitWhitelistSystemMode()434 boolean isImplicitWhitelistSystemMode() { 435 return isImplicitWhitelistSystemMode(getWhitelistMode()); 436 } 437 438 /** 439 * Returns whether the package is a static overlay, whose installation should depend on the 440 * allowlisting of the overlay's target's package name, rather than of its own package name. 441 * 442 * @param pkg A package (which need not be an overlay) 443 */ shouldUseOverlayTargetName(AndroidPackage pkg)444 private static boolean shouldUseOverlayTargetName(AndroidPackage pkg) { 445 return pkg.isOverlayIsStatic(); 446 } 447 448 /** See {@link #isEnforceMode()}. */ isEnforceMode(int whitelistMode)449 private static boolean isEnforceMode(int whitelistMode) { 450 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE) != 0; 451 } 452 453 /** See {@link #isIgnoreOtaMode()}. */ isIgnoreOtaMode(int whitelistMode)454 private static boolean isIgnoreOtaMode(int whitelistMode) { 455 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA) != 0; 456 } 457 458 /** See {@link #isLogMode()}. */ isLogMode(int whitelistMode)459 private static boolean isLogMode(int whitelistMode) { 460 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_LOG) != 0; 461 } 462 463 /** See {@link #isImplicitWhitelistMode()}. */ isImplicitWhitelistMode(int whitelistMode)464 private static boolean isImplicitWhitelistMode(int whitelistMode) { 465 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST) != 0; 466 } 467 468 /** See {@link #isImplicitWhitelistSystemMode()}. */ isImplicitWhitelistSystemMode(int whitelistMode)469 private static boolean isImplicitWhitelistSystemMode(int whitelistMode) { 470 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM) != 0; 471 } 472 473 /** Gets the PackageWhitelistMode for use of {@link #mWhitelistedPackagesForUserTypes}. */ getWhitelistMode()474 private @PackageWhitelistMode int getWhitelistMode() { 475 final int runtimeMode = SystemProperties.getInt( 476 PACKAGE_WHITELIST_MODE_PROP, USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT); 477 if (runtimeMode != USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { 478 return runtimeMode; 479 } 480 return getDeviceDefaultWhitelistMode(); 481 } 482 483 /** Gets the PackageWhitelistMode as defined by {@code config_userTypePackageWhitelistMode}. */ getDeviceDefaultWhitelistMode()484 private @PackageWhitelistMode int getDeviceDefaultWhitelistMode() { 485 return Resources.getSystem() 486 .getInteger(com.android.internal.R.integer.config_userTypePackageWhitelistMode); 487 } 488 modeToString(@ackageWhitelistMode int mode)489 static @NonNull String modeToString(@PackageWhitelistMode int mode) { 490 // Must handle some types separately because they're not bitwise flags 491 switch (mode) { 492 case USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT: 493 return "DEVICE_DEFAULT"; 494 case USER_TYPE_PACKAGE_WHITELIST_MODE_NONE: 495 return "NONE"; 496 default: 497 return DebugUtils.flagsToString(UserSystemPackageInstaller.class, 498 "USER_TYPE_PACKAGE_WHITELIST_MODE_", mode); 499 } 500 } 501 502 /** 503 * Gets the system packages names that should be installed on the given user. 504 * See {@link #getInstallablePackagesForUserType(String)}. 505 */ getInstallablePackagesForUserId(@serIdInt int userId)506 private @Nullable Set<String> getInstallablePackagesForUserId(@UserIdInt int userId) { 507 return getInstallablePackagesForUserType(mUm.getUserInfo(userId).userType); 508 } 509 510 /** 511 * Gets the system package names that should be installed on users of the given user type, as 512 * determined by SystemConfig, the allowlist mode, and the apps actually on the device. 513 * Names are the {@link AndroidPackage#getPackageName()}, not necessarily the manifest names. 514 * 515 * Returns null if all system packages should be installed (due to enforce-mode being off). 516 */ getInstallablePackagesForUserType(String userType)517 @Nullable Set<String> getInstallablePackagesForUserType(String userType) { 518 final int mode = getWhitelistMode(); 519 if (!isEnforceMode(mode)) { 520 return null; 521 } 522 final boolean implicitlyWhitelist = isImplicitWhitelistMode(mode) 523 || (isImplicitWhitelistSystemMode(mode) && mUm.isUserTypeSubtypeOfSystem(userType)); 524 final Set<String> whitelistedPackages = getWhitelistedPackagesForUserType(userType); 525 526 final Set<String> installPackages = new ArraySet<>(); 527 final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); 528 pmInt.forEachPackageState(packageState -> { 529 var pkg = packageState.getAndroidPackage(); 530 if (pkg == null || !packageState.isSystem()) { 531 return; 532 } 533 if (shouldInstallPackage(pkg, mWhitelistedPackagesForUserTypes, 534 whitelistedPackages, implicitlyWhitelist)) { 535 // Although the allowlist uses manifest names, this function returns packageNames. 536 installPackages.add(pkg.getPackageName()); 537 } 538 }); 539 return installPackages; 540 } 541 542 /** 543 * Returns whether the given system package should be installed on the given user, based on the 544 * the given allowlist of system packages. 545 * 546 * @param sysPkg the system package. Must be a system package; no verification for this is done. 547 * @param userTypeWhitelist map of package manifest names to user types on which they should be 548 * installed. This is only used for overriding the userWhitelist in 549 * certain situations (based on its keyset). 550 * @param userWhitelist set of package manifest names that should be installed on this 551 * <b>particular</b> user. This must be consistent with userTypeWhitelist, 552 * but is passed in separately to avoid repeatedly calculating it from 553 * userTypeWhitelist. 554 * @param implicitlyWhitelist whether non-mentioned packages are implicitly allowlisted. 555 */ 556 @VisibleForTesting shouldInstallPackage(AndroidPackage sysPkg, @NonNull ArrayMap<String, Long> userTypeWhitelist, @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist)557 static boolean shouldInstallPackage(AndroidPackage sysPkg, 558 @NonNull ArrayMap<String, Long> userTypeWhitelist, 559 @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist) { 560 final String pkgName = shouldUseOverlayTargetName(sysPkg) ? 561 sysPkg.getOverlayTarget() : sysPkg.getManifestPackageName(); 562 return (implicitlyWhitelist && !userTypeWhitelist.containsKey(pkgName)) 563 || userWhitelist.contains(pkgName) 564 || sysPkg.isApex(); 565 } 566 567 /** 568 * Gets the package manifest names that are allowlisted for users of the given user type, 569 * as determined by SystemConfig. 570 */ 571 @VisibleForTesting getWhitelistedPackagesForUserType(String userType)572 @NonNull Set<String> getWhitelistedPackagesForUserType(String userType) { 573 final long userTypeMask = getUserTypeMask(userType); 574 final Set<String> installablePkgs = new ArraySet<>(mWhitelistedPackagesForUserTypes.size()); 575 for (int i = 0; i < mWhitelistedPackagesForUserTypes.size(); i++) { 576 final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(i); 577 final long whitelistedUserTypes = mWhitelistedPackagesForUserTypes.valueAt(i); 578 if ((userTypeMask & whitelistedUserTypes) != 0) { 579 installablePkgs.add(pkgName); 580 } 581 } 582 return installablePkgs; 583 } 584 585 /** 586 * Set of package manifest names that are included anywhere in the package-to-user-type 587 * allowlist, as determined by SystemConfig. 588 * 589 * Packages that are allowlisted, but then denylisted so that they aren't to be installed on 590 * any user, are still present in this list, since that is a valid scenario (e.g. if an OEM 591 * completely blacklists an AOSP app). 592 */ getWhitelistedSystemPackages()593 private Set<String> getWhitelistedSystemPackages() { 594 return mWhitelistedPackagesForUserTypes.keySet(); 595 } 596 597 /** 598 * Returns a map of package manifest names to the bit set representing (via 599 * {@link #getUserTypeMask}) the user types on which they are to be installed. 600 * Also, clears this data from SystemConfig where it was stored inefficiently (and therefore 601 * should be called exactly once, even if the data isn't useful). 602 * 603 * Any system packages not present in this map should not even be on the device at all. 604 * To enforce this: 605 * <ul> 606 * <li>Illegal user types are ignored.</li> 607 * <li>Packages that never allowlisted at all (even if they are explicitly denylisted) are 608 * ignored.</li> 609 * <li>Packages that are denylisted whenever they are allowlisted will be stored with the 610 * value 0 (since this is a valid scenario, e.g. if an OEM completely blacklists an 611 * AOSP app).</li> 612 * </ul> 613 * 614 * @see #mWhitelistedPackagesForUserTypes 615 */ 616 @VisibleForTesting determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig)617 ArrayMap<String, Long> determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig) { 618 // We first get the list of user types that correspond to FULL, SYSTEM, and PROFILE. 619 final Map<String, Long> baseTypeBitSets = getBaseTypeBitSets(); 620 621 final ArrayMap<String, Set<String>> whitelist = 622 sysConfig.getAndClearPackageToUserTypeWhitelist(); 623 // result maps packageName -> userTypes on which the package should be installed. 624 final ArrayMap<String, Long> result = new ArrayMap<>(whitelist.size() + 1); 625 // First, do the allowlisted user types. 626 for (int i = 0; i < whitelist.size(); i++) { 627 final String pkgName = whitelist.keyAt(i).intern(); 628 final long typesBitSet = getTypesBitSet(whitelist.valueAt(i), baseTypeBitSets); 629 if (typesBitSet != 0) { 630 result.put(pkgName, typesBitSet); 631 } 632 } 633 // Then, un-allowlist any denylisted user types. 634 final ArrayMap<String, Set<String>> blacklist = 635 sysConfig.getAndClearPackageToUserTypeBlacklist(); 636 for (int i = 0; i < blacklist.size(); i++) { 637 final String pkgName = blacklist.keyAt(i).intern(); 638 final long nonTypesBitSet = getTypesBitSet(blacklist.valueAt(i), baseTypeBitSets); 639 final Long typesBitSet = result.get(pkgName); 640 if (typesBitSet != null) { 641 result.put(pkgName, typesBitSet & ~nonTypesBitSet); 642 } else if (nonTypesBitSet != 0) { 643 // Package was never allowlisted but is validly denylisted. 644 result.put(pkgName, 0L); 645 } 646 } 647 // Regardless of the whitelists/blacklists, ensure mandatory packages. 648 result.put("android", ~0L); 649 return result; 650 } 651 652 /** 653 * Returns the bitmask (with exactly one 1) corresponding to the given userType. 654 * Returns 0 if no such userType exists. 655 */ 656 @VisibleForTesting getUserTypeMask(String userType)657 long getUserTypeMask(String userType) { 658 final int userTypeIndex = Arrays.binarySearch(mUserTypes, userType); 659 final long userTypeMask = userTypeIndex >= 0 ? (1 << userTypeIndex) : 0; 660 return userTypeMask; 661 } 662 663 /** 664 * Returns the mapping from the name of each base type to the bitset (as defined by 665 * {@link #getUserTypeMask}) of user types to which it corresponds (i.e. the base's subtypes). 666 * <p> 667 * E.g. if "android.type.ex" is a FULL user type for which getUserTypeMask() returns (1 << 3), 668 * then getBaseTypeBitSets().get("FULL") will contain true (1) in position 3. 669 */ getBaseTypeBitSets()670 private Map<String, Long> getBaseTypeBitSets() { 671 long typesBitSetFull = 0; 672 long typesBitSetSystem = 0; 673 long typesBitSetProfile = 0; 674 for (int idx = 0; idx < mUserTypes.length; idx++) { 675 if (mUm.isUserTypeSubtypeOfFull(mUserTypes[idx])) { 676 typesBitSetFull |= (1 << idx); 677 } 678 if (mUm.isUserTypeSubtypeOfSystem(mUserTypes[idx])) { 679 typesBitSetSystem |= (1 << idx); 680 } 681 if (mUm.isUserTypeSubtypeOfProfile(mUserTypes[idx])) { 682 typesBitSetProfile |= (1 << idx); 683 } 684 } 685 686 Map<String, Long> result = new ArrayMap<>(3); 687 result.put("FULL", typesBitSetFull); 688 result.put("SYSTEM", typesBitSetSystem); 689 result.put("PROFILE", typesBitSetProfile); 690 return result; 691 } 692 693 /** 694 * Converts a list of user types and base types, as used in SystemConfig, to a bit set 695 * representing (via {@link #getUserTypeMask}) user types. 696 * 697 * Returns 0 if userTypes does not contain any valid user or base types. 698 * 699 * @param baseTypeBitSets a map from the base types (FULL/SYSTEM/PROFILE) to their subtypes 700 * (represented as a bitset, as defined by {@link #getUserTypeMask}). 701 * (This can be created by {@link #getBaseTypeBitSets}.) 702 */ getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets)703 private long getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets) { 704 long resultBitSet = 0; 705 for (String type : userTypes) { 706 // See if userType is a base type, like FULL. 707 final Long baseTypeBitSet = baseTypeBitSets.get(type); 708 if (baseTypeBitSet != null) { 709 resultBitSet |= baseTypeBitSet; 710 continue; 711 } 712 // userType wasn't a base type, so it should be the name of a specific user type. 713 final long userTypeBitSet = getUserTypeMask(type); 714 if (userTypeBitSet != 0) { 715 resultBitSet |= userTypeBitSet; 716 continue; 717 } 718 Slog.w(TAG, "SystemConfig contained an invalid user type: " + type); 719 } 720 return resultBitSet; 721 } 722 723 /** Returns a sorted array consisting of the keyset of the provided map. */ getAndSortKeysFromMap(ArrayMap<String, ?> map)724 private static String[] getAndSortKeysFromMap(ArrayMap<String, ?> map) { 725 final String[] userTypeList = new String[map.size()]; 726 for (int i = 0; i < map.size(); i++) { 727 userTypeList[i] = map.keyAt(i); 728 } 729 Arrays.sort(userTypeList); 730 return userTypeList; 731 } 732 dump(IndentingPrintWriter pw)733 void dump(IndentingPrintWriter pw) { 734 final int mode = getWhitelistMode(); 735 pw.println("Whitelisted packages per user type"); 736 737 pw.increaseIndent(); 738 pw.print("Mode: "); 739 pw.print(mode); 740 pw.print(isEnforceMode(mode) ? " (enforced)" : ""); 741 pw.print(isLogMode(mode) ? " (logged)" : ""); 742 pw.print(isImplicitWhitelistMode(mode) ? " (implicit)" : ""); 743 pw.print(isIgnoreOtaMode(mode) ? " (ignore OTAs)" : ""); 744 pw.println(); 745 pw.decreaseIndent(); 746 747 pw.increaseIndent(); 748 pw.println("Legend"); 749 pw.increaseIndent(); 750 for (int idx = 0; idx < mUserTypes.length; idx++) { 751 pw.println(idx + " -> " + mUserTypes[idx]); 752 } 753 pw.decreaseIndent(); pw.decreaseIndent(); 754 755 pw.increaseIndent(); 756 final int size = mWhitelistedPackagesForUserTypes.size(); 757 if (size == 0) { 758 pw.println("No packages"); 759 pw.decreaseIndent(); 760 return; 761 } 762 pw.print(size); pw.println(" packages:"); 763 pw.increaseIndent(); 764 for (int pkgIdx = 0; pkgIdx < size; pkgIdx++) { 765 final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(pkgIdx); 766 pw.print(pkgName); pw.print(": "); 767 final long userTypesBitSet = mWhitelistedPackagesForUserTypes.valueAt(pkgIdx); 768 for (int idx = 0; idx < mUserTypes.length; idx++) { 769 if ((userTypesBitSet & (1 << idx)) != 0) { 770 pw.print(idx); pw.print(" "); 771 } 772 } 773 pw.println(); 774 } 775 pw.decreaseIndent(); pw.decreaseIndent(); 776 777 pw.increaseIndent(); 778 dumpPackageWhitelistProblems(pw, mode, /* verbose= */ true, /* criticalOnly= */ false); 779 pw.decreaseIndent(); 780 } 781 dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode, boolean verbose, boolean criticalOnly)782 void dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode, 783 boolean verbose, boolean criticalOnly) { 784 // Handle special cases first 785 if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_NONE) { 786 mode = getWhitelistMode(); 787 } else if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { 788 mode = getDeviceDefaultWhitelistMode(); 789 } 790 if (criticalOnly) { 791 // Ignore log mode (if set) since log-only issues are not critical. 792 mode &= ~USER_TYPE_PACKAGE_WHITELIST_MODE_LOG; 793 } 794 Slog.v(TAG, "dumpPackageWhitelistProblems(): using mode " + modeToString(mode)); 795 796 final List<String> errors = getPackagesWhitelistErrors(mode); 797 showIssues(pw, verbose, errors, "errors"); 798 799 if (criticalOnly) return; 800 801 final List<String> warnings = getPackagesWhitelistWarnings(); 802 showIssues(pw, verbose, warnings, "warnings"); 803 } 804 showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues, String issueType)805 private static void showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues, 806 String issueType) { 807 final int size = issues.size(); 808 if (size == 0) { 809 if (verbose) { 810 pw.print("No "); pw.println(issueType); 811 } 812 return; 813 } 814 if (verbose) { 815 pw.print(size); pw.print(' '); pw.println(issueType); 816 pw.increaseIndent(); 817 } 818 for (int i = 0; i < size; i++) { 819 pw.println(issues.get(i)); 820 } 821 if (verbose) { 822 pw.decreaseIndent(); 823 } 824 } 825 } 826