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