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