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