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.parsing.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) { 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 final AndroidPackage pkg = pmInt.getPackage(pkgName); 356 if (pkg == null) { 357 warnings.add(String.format(notPresentFmt, pkgName)); 358 } else if (!pkg.isSystem()) { 359 warnings.add(String.format(notSystemFmt, pkgName)); 360 } else if (shouldUseOverlayTargetName(pkg)) { 361 warnings.add(String.format(overlayFmt, pkgName)); 362 } 363 } 364 return warnings; 365 } 366 367 /** 368 * Gets packages that are not listed in the allowlist XMLs when they should be. 369 */ 370 @NonNull getPackagesWhitelistErrors(@ackageWhitelistMode int mode)371 private List<String> getPackagesWhitelistErrors(@PackageWhitelistMode int mode) { 372 if ((!isEnforceMode(mode) || isImplicitWhitelistMode(mode)) && !isLogMode(mode)) { 373 return Collections.emptyList(); 374 } 375 376 final List<String> errors = new ArrayList<>(); 377 final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages(); 378 final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); 379 380 // Check whether all system packages are indeed allowlisted. 381 final String logMessageFmt = "System package %s is not whitelisted using " 382 + "'install-in-user-type' in SystemConfig for any user types!"; 383 pmInt.forEachPackage(pkg -> { 384 if (!pkg.isSystem()) return; 385 final String pkgName = pkg.getManifestPackageName(); 386 if (!allWhitelistedPackages.contains(pkgName) 387 && !shouldUseOverlayTargetName(pmInt.getPackage(pkgName))) { 388 errors.add(String.format(logMessageFmt, pkgName)); 389 } 390 }); 391 392 return errors; 393 } 394 395 /** Whether to only install system packages in new users for which they are allowlisted. */ isEnforceMode()396 boolean isEnforceMode() { 397 return isEnforceMode(getWhitelistMode()); 398 } 399 400 /** 401 * Whether to ignore OTAs, and therefore not install missing system packages during OTAs. 402 * <p>Note: 403 * If in this mode, old system packages will not be installed on pre-existing users during OTAs. 404 * Any system packages that had not been installed at the time of the user's creation, 405 * due to {@link UserSystemPackageInstaller}'s previous actions, will therefore continue to 406 * remain uninstalled, even if the allowlist (or enforcement mode) now declares that they should 407 * be. 408 */ isIgnoreOtaMode()409 boolean isIgnoreOtaMode() { 410 return isIgnoreOtaMode(getWhitelistMode()); 411 } 412 413 /** 414 * Whether to log a warning concerning potential problems with the user-type package allowlist. 415 */ isLogMode()416 boolean isLogMode() { 417 return isLogMode(getWhitelistMode()); 418 } 419 420 /** 421 * Whether to treat all packages that are not mentioned at all in the allowlist to be implicitly 422 * allowlisted for all users. 423 */ isImplicitWhitelistMode()424 boolean isImplicitWhitelistMode() { 425 return isImplicitWhitelistMode(getWhitelistMode()); 426 } 427 428 /** 429 * Whether to treat all packages that are not mentioned at all in the allowlist to be implicitly 430 * allowlisted for the SYSTEM user. 431 */ isImplicitWhitelistSystemMode()432 boolean isImplicitWhitelistSystemMode() { 433 return isImplicitWhitelistSystemMode(getWhitelistMode()); 434 } 435 436 /** 437 * Returns whether the package is a static overlay, whose installation should depend on the 438 * allowlisting of the overlay's target's package name, rather than of its own package name. 439 * 440 * @param pkg A package (which need not be an overlay) 441 */ shouldUseOverlayTargetName(AndroidPackage pkg)442 private static boolean shouldUseOverlayTargetName(AndroidPackage pkg) { 443 return pkg.isOverlayIsStatic(); 444 } 445 446 /** See {@link #isEnforceMode()}. */ isEnforceMode(int whitelistMode)447 private static boolean isEnforceMode(int whitelistMode) { 448 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE) != 0; 449 } 450 451 /** See {@link #isIgnoreOtaMode()}. */ isIgnoreOtaMode(int whitelistMode)452 private static boolean isIgnoreOtaMode(int whitelistMode) { 453 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA) != 0; 454 } 455 456 /** See {@link #isLogMode()}. */ isLogMode(int whitelistMode)457 private static boolean isLogMode(int whitelistMode) { 458 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_LOG) != 0; 459 } 460 461 /** See {@link #isImplicitWhitelistMode()}. */ isImplicitWhitelistMode(int whitelistMode)462 private static boolean isImplicitWhitelistMode(int whitelistMode) { 463 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST) != 0; 464 } 465 466 /** See {@link #isImplicitWhitelistSystemMode()}. */ isImplicitWhitelistSystemMode(int whitelistMode)467 private static boolean isImplicitWhitelistSystemMode(int whitelistMode) { 468 return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM) != 0; 469 } 470 471 /** Gets the PackageWhitelistMode for use of {@link #mWhitelistedPackagesForUserTypes}. */ getWhitelistMode()472 private @PackageWhitelistMode int getWhitelistMode() { 473 final int runtimeMode = SystemProperties.getInt( 474 PACKAGE_WHITELIST_MODE_PROP, USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT); 475 if (runtimeMode != USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { 476 return runtimeMode; 477 } 478 return getDeviceDefaultWhitelistMode(); 479 } 480 481 /** Gets the PackageWhitelistMode as defined by {@code config_userTypePackageWhitelistMode}. */ getDeviceDefaultWhitelistMode()482 private @PackageWhitelistMode int getDeviceDefaultWhitelistMode() { 483 return Resources.getSystem() 484 .getInteger(com.android.internal.R.integer.config_userTypePackageWhitelistMode); 485 } 486 modeToString(@ackageWhitelistMode int mode)487 static @NonNull String modeToString(@PackageWhitelistMode int mode) { 488 // Must handle some types separately because they're not bitwise flags 489 switch (mode) { 490 case USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT: 491 return "DEVICE_DEFAULT"; 492 case USER_TYPE_PACKAGE_WHITELIST_MODE_NONE: 493 return "NONE"; 494 default: 495 return DebugUtils.flagsToString(UserSystemPackageInstaller.class, 496 "USER_TYPE_PACKAGE_WHITELIST_MODE_", mode); 497 } 498 } 499 500 /** 501 * Gets the system packages names that should be installed on the given user. 502 * See {@link #getInstallablePackagesForUserType(String)}. 503 */ getInstallablePackagesForUserId(@serIdInt int userId)504 private @Nullable Set<String> getInstallablePackagesForUserId(@UserIdInt int userId) { 505 return getInstallablePackagesForUserType(mUm.getUserInfo(userId).userType); 506 } 507 508 /** 509 * Gets the system package names that should be installed on users of the given user type, as 510 * determined by SystemConfig, the allowlist mode, and the apps actually on the device. 511 * Names are the {@link AndroidPackage#getPackageName()}, not necessarily the manifest names. 512 * 513 * Returns null if all system packages should be installed (due to enforce-mode being off). 514 */ getInstallablePackagesForUserType(String userType)515 @Nullable Set<String> getInstallablePackagesForUserType(String userType) { 516 final int mode = getWhitelistMode(); 517 if (!isEnforceMode(mode)) { 518 return null; 519 } 520 final boolean implicitlyWhitelist = isImplicitWhitelistMode(mode) 521 || (isImplicitWhitelistSystemMode(mode) && mUm.isUserTypeSubtypeOfSystem(userType)); 522 final Set<String> whitelistedPackages = getWhitelistedPackagesForUserType(userType); 523 524 final Set<String> installPackages = new ArraySet<>(); 525 final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); 526 pmInt.forEachPackage(pkg -> { 527 if (!pkg.isSystem()) { 528 return; 529 } 530 if (shouldInstallPackage(pkg, mWhitelistedPackagesForUserTypes, 531 whitelistedPackages, implicitlyWhitelist)) { 532 // Although the allowlist uses manifest names, this function returns packageNames. 533 installPackages.add(pkg.getPackageName()); 534 } 535 }); 536 return installPackages; 537 } 538 539 /** 540 * Returns whether the given system package should be installed on the given user, based on the 541 * the given allowlist of system packages. 542 * 543 * @param sysPkg the system package. Must be a system package; no verification for this is done. 544 * @param userTypeWhitelist map of package manifest names to user types on which they should be 545 * installed. This is only used for overriding the userWhitelist in 546 * certain situations (based on its keyset). 547 * @param userWhitelist set of package manifest names that should be installed on this 548 * <b>particular</b> user. This must be consistent with userTypeWhitelist, 549 * but is passed in separately to avoid repeatedly calculating it from 550 * userTypeWhitelist. 551 * @param implicitlyWhitelist whether non-mentioned packages are implicitly allowlisted. 552 */ 553 @VisibleForTesting shouldInstallPackage(AndroidPackage sysPkg, @NonNull ArrayMap<String, Long> userTypeWhitelist, @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist)554 static boolean shouldInstallPackage(AndroidPackage sysPkg, 555 @NonNull ArrayMap<String, Long> userTypeWhitelist, 556 @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist) { 557 final String pkgName = shouldUseOverlayTargetName(sysPkg) ? 558 sysPkg.getOverlayTarget() : sysPkg.getManifestPackageName(); 559 return (implicitlyWhitelist && !userTypeWhitelist.containsKey(pkgName)) 560 || userWhitelist.contains(pkgName); 561 } 562 563 /** 564 * Gets the package manifest names that are allowlisted for users of the given user type, 565 * as determined by SystemConfig. 566 */ 567 @VisibleForTesting getWhitelistedPackagesForUserType(String userType)568 @NonNull Set<String> getWhitelistedPackagesForUserType(String userType) { 569 final long userTypeMask = getUserTypeMask(userType); 570 final Set<String> installablePkgs = new ArraySet<>(mWhitelistedPackagesForUserTypes.size()); 571 for (int i = 0; i < mWhitelistedPackagesForUserTypes.size(); i++) { 572 final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(i); 573 final long whitelistedUserTypes = mWhitelistedPackagesForUserTypes.valueAt(i); 574 if ((userTypeMask & whitelistedUserTypes) != 0) { 575 installablePkgs.add(pkgName); 576 } 577 } 578 return installablePkgs; 579 } 580 581 /** 582 * Set of package manifest names that are included anywhere in the package-to-user-type 583 * allowlist, as determined by SystemConfig. 584 * 585 * Packages that are allowlisted, but then denylisted so that they aren't to be installed on 586 * any user, are still present in this list, since that is a valid scenario (e.g. if an OEM 587 * completely blacklists an AOSP app). 588 */ getWhitelistedSystemPackages()589 private Set<String> getWhitelistedSystemPackages() { 590 return mWhitelistedPackagesForUserTypes.keySet(); 591 } 592 593 /** 594 * Returns a map of package manifest names to the bit set representing (via 595 * {@link #getUserTypeMask}) the user types on which they are to be installed. 596 * Also, clears this data from SystemConfig where it was stored inefficiently (and therefore 597 * should be called exactly once, even if the data isn't useful). 598 * 599 * Any system packages not present in this map should not even be on the device at all. 600 * To enforce this: 601 * <ul> 602 * <li>Illegal user types are ignored.</li> 603 * <li>Packages that never allowlisted at all (even if they are explicitly denylisted) are 604 * ignored.</li> 605 * <li>Packages that are denylisted whenever they are allowlisted will be stored with the 606 * value 0 (since this is a valid scenario, e.g. if an OEM completely blacklists an 607 * AOSP app).</li> 608 * </ul> 609 * 610 * @see #mWhitelistedPackagesForUserTypes 611 */ 612 @VisibleForTesting determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig)613 ArrayMap<String, Long> determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig) { 614 // We first get the list of user types that correspond to FULL, SYSTEM, and PROFILE. 615 final Map<String, Long> baseTypeBitSets = getBaseTypeBitSets(); 616 617 final ArrayMap<String, Set<String>> whitelist = 618 sysConfig.getAndClearPackageToUserTypeWhitelist(); 619 // result maps packageName -> userTypes on which the package should be installed. 620 final ArrayMap<String, Long> result = new ArrayMap<>(whitelist.size() + 1); 621 // First, do the allowlisted user types. 622 for (int i = 0; i < whitelist.size(); i++) { 623 final String pkgName = whitelist.keyAt(i).intern(); 624 final long typesBitSet = getTypesBitSet(whitelist.valueAt(i), baseTypeBitSets); 625 if (typesBitSet != 0) { 626 result.put(pkgName, typesBitSet); 627 } 628 } 629 // Then, un-allowlist any denylisted user types. 630 final ArrayMap<String, Set<String>> blacklist = 631 sysConfig.getAndClearPackageToUserTypeBlacklist(); 632 for (int i = 0; i < blacklist.size(); i++) { 633 final String pkgName = blacklist.keyAt(i).intern(); 634 final long nonTypesBitSet = getTypesBitSet(blacklist.valueAt(i), baseTypeBitSets); 635 final Long typesBitSet = result.get(pkgName); 636 if (typesBitSet != null) { 637 result.put(pkgName, typesBitSet & ~nonTypesBitSet); 638 } else if (nonTypesBitSet != 0) { 639 // Package was never allowlisted but is validly denylisted. 640 result.put(pkgName, 0L); 641 } 642 } 643 // Regardless of the whitelists/blacklists, ensure mandatory packages. 644 result.put("android", ~0L); 645 return result; 646 } 647 648 /** 649 * Returns the bitmask (with exactly one 1) corresponding to the given userType. 650 * Returns 0 if no such userType exists. 651 */ 652 @VisibleForTesting getUserTypeMask(String userType)653 long getUserTypeMask(String userType) { 654 final int userTypeIndex = Arrays.binarySearch(mUserTypes, userType); 655 final long userTypeMask = userTypeIndex >= 0 ? (1 << userTypeIndex) : 0; 656 return userTypeMask; 657 } 658 659 /** 660 * Returns the mapping from the name of each base type to the bitset (as defined by 661 * {@link #getUserTypeMask}) of user types to which it corresponds (i.e. the base's subtypes). 662 * <p> 663 * E.g. if "android.type.ex" is a FULL user type for which getUserTypeMask() returns (1 << 3), 664 * then getBaseTypeBitSets().get("FULL") will contain true (1) in position 3. 665 */ getBaseTypeBitSets()666 private Map<String, Long> getBaseTypeBitSets() { 667 long typesBitSetFull = 0; 668 long typesBitSetSystem = 0; 669 long typesBitSetProfile = 0; 670 for (int idx = 0; idx < mUserTypes.length; idx++) { 671 if (mUm.isUserTypeSubtypeOfFull(mUserTypes[idx])) { 672 typesBitSetFull |= (1 << idx); 673 } 674 if (mUm.isUserTypeSubtypeOfSystem(mUserTypes[idx])) { 675 typesBitSetSystem |= (1 << idx); 676 } 677 if (mUm.isUserTypeSubtypeOfProfile(mUserTypes[idx])) { 678 typesBitSetProfile |= (1 << idx); 679 } 680 } 681 682 Map<String, Long> result = new ArrayMap<>(3); 683 result.put("FULL", typesBitSetFull); 684 result.put("SYSTEM", typesBitSetSystem); 685 result.put("PROFILE", typesBitSetProfile); 686 return result; 687 } 688 689 /** 690 * Converts a list of user types and base types, as used in SystemConfig, to a bit set 691 * representing (via {@link #getUserTypeMask}) user types. 692 * 693 * Returns 0 if userTypes does not contain any valid user or base types. 694 * 695 * @param baseTypeBitSets a map from the base types (FULL/SYSTEM/PROFILE) to their subtypes 696 * (represented as a bitset, as defined by {@link #getUserTypeMask}). 697 * (This can be created by {@link #getBaseTypeBitSets}.) 698 */ getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets)699 private long getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets) { 700 long resultBitSet = 0; 701 for (String type : userTypes) { 702 // See if userType is a base type, like FULL. 703 final Long baseTypeBitSet = baseTypeBitSets.get(type); 704 if (baseTypeBitSet != null) { 705 resultBitSet |= baseTypeBitSet; 706 continue; 707 } 708 // userType wasn't a base type, so it should be the name of a specific user type. 709 final long userTypeBitSet = getUserTypeMask(type); 710 if (userTypeBitSet != 0) { 711 resultBitSet |= userTypeBitSet; 712 continue; 713 } 714 Slog.w(TAG, "SystemConfig contained an invalid user type: " + type); 715 } 716 return resultBitSet; 717 } 718 719 /** Returns a sorted array consisting of the keyset of the provided map. */ getAndSortKeysFromMap(ArrayMap<String, ?> map)720 private static String[] getAndSortKeysFromMap(ArrayMap<String, ?> map) { 721 final String[] userTypeList = new String[map.size()]; 722 for (int i = 0; i < map.size(); i++) { 723 userTypeList[i] = map.keyAt(i); 724 } 725 Arrays.sort(userTypeList); 726 return userTypeList; 727 } 728 dump(IndentingPrintWriter pw)729 void dump(IndentingPrintWriter pw) { 730 final int mode = getWhitelistMode(); 731 pw.println("Whitelisted packages per user type"); 732 733 pw.increaseIndent(); 734 pw.print("Mode: "); 735 pw.print(mode); 736 pw.print(isEnforceMode(mode) ? " (enforced)" : ""); 737 pw.print(isLogMode(mode) ? " (logged)" : ""); 738 pw.print(isImplicitWhitelistMode(mode) ? " (implicit)" : ""); 739 pw.print(isIgnoreOtaMode(mode) ? " (ignore OTAs)" : ""); 740 pw.println(); 741 pw.decreaseIndent(); 742 743 pw.increaseIndent(); 744 pw.println("Legend"); 745 pw.increaseIndent(); 746 for (int idx = 0; idx < mUserTypes.length; idx++) { 747 pw.println(idx + " -> " + mUserTypes[idx]); 748 } 749 pw.decreaseIndent(); pw.decreaseIndent(); 750 751 pw.increaseIndent(); 752 final int size = mWhitelistedPackagesForUserTypes.size(); 753 if (size == 0) { 754 pw.println("No packages"); 755 pw.decreaseIndent(); 756 return; 757 } 758 pw.print(size); pw.println(" packages:"); 759 pw.increaseIndent(); 760 for (int pkgIdx = 0; pkgIdx < size; pkgIdx++) { 761 final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(pkgIdx); 762 pw.print(pkgName); pw.print(": "); 763 final long userTypesBitSet = mWhitelistedPackagesForUserTypes.valueAt(pkgIdx); 764 for (int idx = 0; idx < mUserTypes.length; idx++) { 765 if ((userTypesBitSet & (1 << idx)) != 0) { 766 pw.print(idx); pw.print(" "); 767 } 768 } 769 pw.println(); 770 } 771 pw.decreaseIndent(); pw.decreaseIndent(); 772 773 pw.increaseIndent(); 774 dumpPackageWhitelistProblems(pw, mode, /* verbose= */ true, /* criticalOnly= */ false); 775 pw.decreaseIndent(); 776 } 777 dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode, boolean verbose, boolean criticalOnly)778 void dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode, 779 boolean verbose, boolean criticalOnly) { 780 // Handle special cases first 781 if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_NONE) { 782 mode = getWhitelistMode(); 783 } else if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { 784 mode = getDeviceDefaultWhitelistMode(); 785 } 786 if (criticalOnly) { 787 // Ignore log mode (if set) since log-only issues are not critical. 788 mode &= ~USER_TYPE_PACKAGE_WHITELIST_MODE_LOG; 789 } 790 Slog.v(TAG, "dumpPackageWhitelistProblems(): using mode " + modeToString(mode)); 791 792 final List<String> errors = getPackagesWhitelistErrors(mode); 793 showIssues(pw, verbose, errors, "errors"); 794 795 if (criticalOnly) return; 796 797 final List<String> warnings = getPackagesWhitelistWarnings(); 798 showIssues(pw, verbose, warnings, "warnings"); 799 } 800 showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues, String issueType)801 private static void showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues, 802 String issueType) { 803 final int size = issues.size(); 804 if (size == 0) { 805 if (verbose) { 806 pw.print("No "); pw.println(issueType); 807 } 808 return; 809 } 810 if (verbose) { 811 pw.print(size); pw.print(' '); pw.println(issueType); 812 pw.increaseIndent(); 813 } 814 for (int i = 0; i < size; i++) { 815 pw.println(issues.get(i)); 816 } 817 if (verbose) { 818 pw.decreaseIndent(); 819 } 820 } 821 } 822