PermissionManagerService.java revision ef9acb6ed97ececa4c8554adb693ec948a963db1
1/*
2 * Copyright (C) 2017 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
17package com.android.server.pm.permission;
18
19import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
21import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
22import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
23import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
24import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
25import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
26import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
27import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
28
29import android.Manifest;
30import android.annotation.NonNull;
31import android.annotation.Nullable;
32import android.content.Context;
33import android.content.pm.PackageManager;
34import android.content.pm.PackageManagerInternal;
35import android.content.pm.PackageParser;
36import android.content.pm.PermissionGroupInfo;
37import android.content.pm.PermissionInfo;
38import android.content.pm.PackageParser.Package;
39import android.metrics.LogMaker;
40import android.os.Binder;
41import android.os.Build;
42import android.os.Handler;
43import android.os.HandlerThread;
44import android.os.Process;
45import android.os.Trace;
46import android.os.UserHandle;
47import android.os.UserManager;
48import android.os.UserManagerInternal;
49import android.os.storage.StorageManager;
50import android.os.storage.StorageManagerInternal;
51import android.text.TextUtils;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.EventLog;
55import android.util.Log;
56import android.util.Slog;
57import android.util.SparseArray;
58
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.logging.MetricsLogger;
61import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
62import com.android.internal.os.RoSystemProperties;
63import com.android.internal.util.ArrayUtils;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemConfig;
67import com.android.server.Watchdog;
68import com.android.server.pm.PackageManagerServiceUtils;
69import com.android.server.pm.PackageSetting;
70import com.android.server.pm.SharedUserSetting;
71import com.android.server.pm.UserManagerService;
72import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
73import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
74import com.android.server.pm.permission.PermissionsState.PermissionState;
75
76import libcore.util.EmptyArray;
77
78import java.util.ArrayList;
79import java.util.Arrays;
80import java.util.Collection;
81import java.util.Iterator;
82import java.util.List;
83import java.util.Objects;
84import java.util.Set;
85
86/**
87 * Manages all permissions and handles permissions related tasks.
88 */
89public class PermissionManagerService {
90    private static final String TAG = "PackageManager";
91
92    /** Permission grant: not grant the permission. */
93    private static final int GRANT_DENIED = 1;
94    /** Permission grant: grant the permission as an install permission. */
95    private static final int GRANT_INSTALL = 2;
96    /** Permission grant: grant the permission as a runtime one. */
97    private static final int GRANT_RUNTIME = 3;
98    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
99    private static final int GRANT_UPGRADE = 4;
100
101    /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
102    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
103    /** Empty array to avoid allocations */
104    private static final int[] EMPTY_INT_ARRAY = new int[0];
105
106    /** Lock to protect internal data access */
107    private final Object mLock;
108
109    /** Internal connection to the package manager */
110    private final PackageManagerInternal mPackageManagerInt;
111
112    /** Internal connection to the user manager */
113    private final UserManagerInternal mUserManagerInt;
114
115    /** Default permission policy to provide proper behaviour out-of-the-box */
116    private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
117
118    /**
119     * Built-in permissions. Read from system configuration files. Mapping is from
120     * UID to permission name.
121     */
122    private final SparseArray<ArraySet<String>> mSystemPermissions;
123
124    /** Built-in group IDs given to all packages. Read from system configuration files. */
125    private final int[] mGlobalGids;
126
127    private final HandlerThread mHandlerThread;
128    private final Handler mHandler;
129    private final Context mContext;
130    private final MetricsLogger mMetricsLogger = new MetricsLogger();
131
132    /** Internal storage for permissions and related settings */
133    @GuardedBy("mLock")
134    private final PermissionSettings mSettings;
135
136    @GuardedBy("mLock")
137    private ArraySet<String> mPrivappPermissionsViolations;
138
139    @GuardedBy("mLock")
140    private boolean mSystemReady;
141
142    PermissionManagerService(Context context,
143            @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
144            @NonNull Object externalLock) {
145        mContext = context;
146        mLock = externalLock;
147        mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
148        mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
149        mSettings = new PermissionSettings(context, mLock);
150
151        mHandlerThread = new ServiceThread(TAG,
152                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
153        mHandlerThread.start();
154        mHandler = new Handler(mHandlerThread.getLooper());
155        Watchdog.getInstance().addThread(mHandler);
156
157        mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
158                context, mHandlerThread.getLooper(), defaultGrantCallback, this);
159        SystemConfig systemConfig = SystemConfig.getInstance();
160        mSystemPermissions = systemConfig.getSystemPermissions();
161        mGlobalGids = systemConfig.getGlobalGids();
162
163        // propagate permission configuration
164        final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
165                SystemConfig.getInstance().getPermissions();
166        synchronized (mLock) {
167            for (int i=0; i<permConfig.size(); i++) {
168                final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
169                BasePermission bp = mSettings.getPermissionLocked(perm.name);
170                if (bp == null) {
171                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
172                    mSettings.putPermissionLocked(perm.name, bp);
173                }
174                if (perm.gids != null) {
175                    bp.setGids(perm.gids, perm.perUser);
176                }
177            }
178        }
179
180        LocalServices.addService(
181                PermissionManagerInternal.class, new PermissionManagerInternalImpl());
182    }
183
184    /**
185     * Creates and returns an initialized, internal service for use by other components.
186     * <p>
187     * The object returned is identical to the one returned by the LocalServices class using:
188     * {@code LocalServices.getService(PermissionManagerInternal.class);}
189     * <p>
190     * NOTE: The external lock is temporary and should be removed. This needs to be a
191     * lock created by the permission manager itself.
192     */
193    public static PermissionManagerInternal create(Context context,
194            @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
195            @NonNull Object externalLock) {
196        final PermissionManagerInternal permMgrInt =
197                LocalServices.getService(PermissionManagerInternal.class);
198        if (permMgrInt != null) {
199            return permMgrInt;
200        }
201        new PermissionManagerService(context, defaultGrantCallback, externalLock);
202        return LocalServices.getService(PermissionManagerInternal.class);
203    }
204
205    @Nullable BasePermission getPermission(String permName) {
206        synchronized (mLock) {
207            return mSettings.getPermissionLocked(permName);
208        }
209    }
210
211    private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
212        if (!mUserManagerInt.exists(userId)) {
213            return PackageManager.PERMISSION_DENIED;
214        }
215
216        final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
217        if (pkg != null && pkg.mExtras != null) {
218            if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
219                return PackageManager.PERMISSION_DENIED;
220            }
221            final PackageSetting ps = (PackageSetting) pkg.mExtras;
222            final boolean instantApp = ps.getInstantApp(userId);
223            final PermissionsState permissionsState = ps.getPermissionsState();
224            if (permissionsState.hasPermission(permName, userId)) {
225                if (instantApp) {
226                    synchronized (mLock) {
227                        BasePermission bp = mSettings.getPermissionLocked(permName);
228                        if (bp != null && bp.isInstant()) {
229                            return PackageManager.PERMISSION_GRANTED;
230                        }
231                    }
232                } else {
233                    return PackageManager.PERMISSION_GRANTED;
234                }
235            }
236            // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
237            if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
238                    .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
239                return PackageManager.PERMISSION_GRANTED;
240            }
241        }
242
243        return PackageManager.PERMISSION_DENIED;
244    }
245
246    private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
247            int callingUid) {
248        final int callingUserId = UserHandle.getUserId(callingUid);
249        final boolean isCallerInstantApp =
250                mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
251        final boolean isUidInstantApp =
252                mPackageManagerInt.getInstantAppPackageName(uid) != null;
253        final int userId = UserHandle.getUserId(uid);
254        if (!mUserManagerInt.exists(userId)) {
255            return PackageManager.PERMISSION_DENIED;
256        }
257
258        if (pkg != null) {
259            if (pkg.mSharedUserId != null) {
260                if (isCallerInstantApp) {
261                    return PackageManager.PERMISSION_DENIED;
262                }
263            } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
264                return PackageManager.PERMISSION_DENIED;
265            }
266            final PermissionsState permissionsState =
267                    ((PackageSetting) pkg.mExtras).getPermissionsState();
268            if (permissionsState.hasPermission(permName, userId)) {
269                if (isUidInstantApp) {
270                    if (mSettings.isPermissionInstant(permName)) {
271                        return PackageManager.PERMISSION_GRANTED;
272                    }
273                } else {
274                    return PackageManager.PERMISSION_GRANTED;
275                }
276            }
277            // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
278            if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
279                    .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
280                return PackageManager.PERMISSION_GRANTED;
281            }
282        } else {
283            ArraySet<String> perms = mSystemPermissions.get(uid);
284            if (perms != null) {
285                if (perms.contains(permName)) {
286                    return PackageManager.PERMISSION_GRANTED;
287                }
288                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
289                        .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
290                    return PackageManager.PERMISSION_GRANTED;
291                }
292            }
293        }
294        return PackageManager.PERMISSION_DENIED;
295    }
296
297    private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
298            int callingUid) {
299        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
300            return null;
301        }
302        synchronized (mLock) {
303            return PackageParser.generatePermissionGroupInfo(
304                    mSettings.mPermissionGroups.get(groupName), flags);
305        }
306    }
307
308    private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
309        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
310            return null;
311        }
312        synchronized (mLock) {
313            final int N = mSettings.mPermissionGroups.size();
314            final ArrayList<PermissionGroupInfo> out
315                    = new ArrayList<PermissionGroupInfo>(N);
316            for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
317                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
318            }
319            return out;
320        }
321    }
322
323    private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
324            int callingUid) {
325        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
326            return null;
327        }
328        // reader
329        synchronized (mLock) {
330            final BasePermission bp = mSettings.getPermissionLocked(permName);
331            if (bp == null) {
332                return null;
333            }
334            final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
335                    bp.getProtectionLevel(), packageName, callingUid);
336            return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
337        }
338    }
339
340    private List<PermissionInfo> getPermissionInfoByGroup(
341            String groupName, int flags, int callingUid) {
342        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
343            return null;
344        }
345        synchronized (mLock) {
346            if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
347                return null;
348            }
349            final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
350            for (BasePermission bp : mSettings.mPermissions.values()) {
351                final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
352                if (pi != null) {
353                    out.add(pi);
354                }
355            }
356            return out;
357        }
358    }
359
360    private int adjustPermissionProtectionFlagsLocked(
361            int protectionLevel, String packageName, int uid) {
362        // Signature permission flags area always reported
363        final int protectionLevelMasked = protectionLevel
364                & (PermissionInfo.PROTECTION_NORMAL
365                | PermissionInfo.PROTECTION_DANGEROUS
366                | PermissionInfo.PROTECTION_SIGNATURE);
367        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
368            return protectionLevel;
369        }
370        // System sees all flags.
371        final int appId = UserHandle.getAppId(uid);
372        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
373                || appId == Process.SHELL_UID) {
374            return protectionLevel;
375        }
376        // Normalize package name to handle renamed packages and static libs
377        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
378        if (pkg == null) {
379            return protectionLevel;
380        }
381        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
382            return protectionLevelMasked;
383        }
384        // Apps that target O see flags for all protection levels.
385        final PackageSetting ps = (PackageSetting) pkg.mExtras;
386        if (ps == null) {
387            return protectionLevel;
388        }
389        if (ps.getAppId() != appId) {
390            return protectionLevel;
391        }
392        return protectionLevel;
393    }
394
395    /**
396     * We might auto-grant permissions if any permission of the group is already granted. Hence if
397     * the group of a granted permission changes we need to revoke it to avoid having permissions of
398     * the new group auto-granted.
399     *
400     * @param newPackage The new package that was installed
401     * @param oldPackage The old package that was updated
402     * @param allPackageNames All package names
403     * @param permissionCallback Callback for permission changed
404     */
405    private void revokeRuntimePermissionsIfGroupChanged(
406            @NonNull PackageParser.Package newPackage,
407            @NonNull PackageParser.Package oldPackage,
408            @NonNull ArrayList<String> allPackageNames,
409            @NonNull PermissionCallback permissionCallback) {
410        final int numOldPackagePermissions = oldPackage.permissions.size();
411        final ArrayMap<String, String> oldPermissionNameToGroupName
412                = new ArrayMap<>(numOldPackagePermissions);
413
414        for (int i = 0; i < numOldPackagePermissions; i++) {
415            final PackageParser.Permission permission = oldPackage.permissions.get(i);
416
417            if (permission.group != null) {
418                oldPermissionNameToGroupName.put(permission.info.name,
419                        permission.group.info.name);
420            }
421        }
422
423        final int numNewPackagePermissions = newPackage.permissions.size();
424        for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
425                newPermissionNum++) {
426            final PackageParser.Permission newPermission =
427                    newPackage.permissions.get(newPermissionNum);
428            final int newProtection = newPermission.info.getProtection();
429
430            if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
431                final String permissionName = newPermission.info.name;
432                final String newPermissionGroupName =
433                        newPermission.group == null ? null : newPermission.group.info.name;
434                final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
435                        permissionName);
436
437                if (newPermissionGroupName != null
438                        && !newPermissionGroupName.equals(oldPermissionGroupName)) {
439                    final int[] userIds = mUserManagerInt.getUserIds();
440                    final int numUserIds = userIds.length;
441                    for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
442                        final int userId = userIds[userIdNum];
443
444                        final int numPackages = allPackageNames.size();
445                        for (int packageNum = 0; packageNum < numPackages; packageNum++) {
446                            final String packageName = allPackageNames.get(packageNum);
447
448                            if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
449                                    userId) == PackageManager.PERMISSION_GRANTED) {
450                                EventLog.writeEvent(0x534e4554, "72710897",
451                                        newPackage.applicationInfo.uid,
452                                        "Revoking permission " + permissionName +
453                                        " from package " + packageName +
454                                        " as the group changed from " + oldPermissionGroupName +
455                                        " to " + newPermissionGroupName);
456
457                                try {
458                                    revokeRuntimePermission(permissionName, packageName, false,
459                                            Process.SYSTEM_UID, userId, permissionCallback);
460                                } catch (IllegalArgumentException e) {
461                                    Slog.e(TAG, "Could not revoke " + permissionName + " from "
462                                            + packageName, e);
463                                }
464                            }
465                        }
466                    }
467                }
468            }
469        }
470    }
471
472    private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
473        final int N = pkg.permissions.size();
474        for (int i=0; i<N; i++) {
475            PackageParser.Permission p = pkg.permissions.get(i);
476
477            // Assume by default that we did not install this permission into the system.
478            p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
479
480            synchronized (PermissionManagerService.this.mLock) {
481                // Now that permission groups have a special meaning, we ignore permission
482                // groups for legacy apps to prevent unexpected behavior. In particular,
483                // permissions for one app being granted to someone just because they happen
484                // to be in a group defined by another app (before this had no implications).
485                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
486                    p.group = mSettings.mPermissionGroups.get(p.info.group);
487                    // Warn for a permission in an unknown group.
488                    if (DEBUG_PERMISSIONS
489                            && p.info.group != null && p.group == null) {
490                        Slog.i(TAG, "Permission " + p.info.name + " from package "
491                                + p.info.packageName + " in an unknown group " + p.info.group);
492                    }
493                }
494
495                if (p.tree) {
496                    final BasePermission bp = BasePermission.createOrUpdate(
497                            mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
498                            mSettings.getAllPermissionTreesLocked(), chatty);
499                    mSettings.putPermissionTreeLocked(p.info.name, bp);
500                } else {
501                    final BasePermission bp = BasePermission.createOrUpdate(
502                            mSettings.getPermissionLocked(p.info.name),
503                            p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
504                    mSettings.putPermissionLocked(p.info.name, bp);
505                }
506            }
507        }
508    }
509
510    private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
511        final int N = pkg.permissionGroups.size();
512        StringBuilder r = null;
513        for (int i=0; i<N; i++) {
514            final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
515            final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
516            final String curPackageName = (cur == null) ? null : cur.info.packageName;
517            final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
518            if (cur == null || isPackageUpdate) {
519                mSettings.mPermissionGroups.put(pg.info.name, pg);
520                if (chatty && DEBUG_PACKAGE_SCANNING) {
521                    if (r == null) {
522                        r = new StringBuilder(256);
523                    } else {
524                        r.append(' ');
525                    }
526                    if (isPackageUpdate) {
527                        r.append("UPD:");
528                    }
529                    r.append(pg.info.name);
530                }
531            } else {
532                Slog.w(TAG, "Permission group " + pg.info.name + " from package "
533                        + pg.info.packageName + " ignored: original from "
534                        + cur.info.packageName);
535                if (chatty && DEBUG_PACKAGE_SCANNING) {
536                    if (r == null) {
537                        r = new StringBuilder(256);
538                    } else {
539                        r.append(' ');
540                    }
541                    r.append("DUP:");
542                    r.append(pg.info.name);
543                }
544            }
545        }
546        if (r != null && DEBUG_PACKAGE_SCANNING) {
547            Log.d(TAG, "  Permission Groups: " + r);
548        }
549
550    }
551
552    private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
553        synchronized (mLock) {
554            int N = pkg.permissions.size();
555            StringBuilder r = null;
556            for (int i=0; i<N; i++) {
557                PackageParser.Permission p = pkg.permissions.get(i);
558                BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
559                if (bp == null) {
560                    bp = mSettings.mPermissionTrees.get(p.info.name);
561                }
562                if (bp != null && bp.isPermission(p)) {
563                    bp.setPermission(null);
564                    if (DEBUG_REMOVE && chatty) {
565                        if (r == null) {
566                            r = new StringBuilder(256);
567                        } else {
568                            r.append(' ');
569                        }
570                        r.append(p.info.name);
571                    }
572                }
573                if (p.isAppOp()) {
574                    ArraySet<String> appOpPkgs =
575                            mSettings.mAppOpPermissionPackages.get(p.info.name);
576                    if (appOpPkgs != null) {
577                        appOpPkgs.remove(pkg.packageName);
578                    }
579                }
580            }
581            if (r != null) {
582                if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
583            }
584
585            N = pkg.requestedPermissions.size();
586            r = null;
587            for (int i=0; i<N; i++) {
588                String perm = pkg.requestedPermissions.get(i);
589                if (mSettings.isPermissionAppOp(perm)) {
590                    ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
591                    if (appOpPkgs != null) {
592                        appOpPkgs.remove(pkg.packageName);
593                        if (appOpPkgs.isEmpty()) {
594                            mSettings.mAppOpPermissionPackages.remove(perm);
595                        }
596                    }
597                }
598            }
599            if (r != null) {
600                if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
601            }
602        }
603    }
604
605    private boolean addDynamicPermission(
606            PermissionInfo info, int callingUid, PermissionCallback callback) {
607        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
608            throw new SecurityException("Instant apps can't add permissions");
609        }
610        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
611            throw new SecurityException("Label must be specified in permission");
612        }
613        final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
614        final boolean added;
615        final boolean changed;
616        synchronized (mLock) {
617            BasePermission bp = mSettings.getPermissionLocked(info.name);
618            added = bp == null;
619            int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
620            if (added) {
621                enforcePermissionCapLocked(info, tree);
622                bp = new BasePermission(info.name, tree.getSourcePackageName(),
623                        BasePermission.TYPE_DYNAMIC);
624            } else if (!bp.isDynamic()) {
625                throw new SecurityException("Not allowed to modify non-dynamic permission "
626                        + info.name);
627            }
628            changed = bp.addToTree(fixedLevel, info, tree);
629            if (added) {
630                mSettings.putPermissionLocked(info.name, bp);
631            }
632        }
633        if (changed && callback != null) {
634            callback.onPermissionChanged();
635        }
636        return added;
637    }
638
639    private void removeDynamicPermission(
640            String permName, int callingUid, PermissionCallback callback) {
641        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
642            throw new SecurityException("Instant applications don't have access to this method");
643        }
644        final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
645        synchronized (mLock) {
646            final BasePermission bp = mSettings.getPermissionLocked(permName);
647            if (bp == null) {
648                return;
649            }
650            if (bp.isDynamic()) {
651                // TODO: switch this back to SecurityException
652                Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
653                        + permName);
654            }
655            mSettings.removePermissionLocked(permName);
656            if (callback != null) {
657                callback.onPermissionRemoved();
658            }
659        }
660    }
661
662    private void grantPermissions(PackageParser.Package pkg, boolean replace,
663            String packageOfInterest, PermissionCallback callback) {
664        // IMPORTANT: There are two types of permissions: install and runtime.
665        // Install time permissions are granted when the app is installed to
666        // all device users and users added in the future. Runtime permissions
667        // are granted at runtime explicitly to specific users. Normal and signature
668        // protected permissions are install time permissions. Dangerous permissions
669        // are install permissions if the app's target SDK is Lollipop MR1 or older,
670        // otherwise they are runtime permissions. This function does not manage
671        // runtime permissions except for the case an app targeting Lollipop MR1
672        // being upgraded to target a newer SDK, in which case dangerous permissions
673        // are transformed from install time to runtime ones.
674
675        final PackageSetting ps = (PackageSetting) pkg.mExtras;
676        if (ps == null) {
677            return;
678        }
679        final boolean isLegacySystemApp = mPackageManagerInt.isLegacySystemApp(pkg);
680
681        final PermissionsState permissionsState = ps.getPermissionsState();
682        PermissionsState origPermissions = permissionsState;
683
684        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
685
686        boolean runtimePermissionsRevoked = false;
687        int[] updatedUserIds = EMPTY_INT_ARRAY;
688
689        boolean changedInstallPermission = false;
690
691        if (replace) {
692            ps.setInstallPermissionsFixed(false);
693            if (!ps.isSharedUser()) {
694                origPermissions = new PermissionsState(permissionsState);
695                permissionsState.reset();
696            } else {
697                // We need to know only about runtime permission changes since the
698                // calling code always writes the install permissions state but
699                // the runtime ones are written only if changed. The only cases of
700                // changed runtime permissions here are promotion of an install to
701                // runtime and revocation of a runtime from a shared user.
702                synchronized (mLock) {
703                    updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
704                            ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
705                    if (!ArrayUtils.isEmpty(updatedUserIds)) {
706                        runtimePermissionsRevoked = true;
707                    }
708                }
709            }
710        }
711
712        permissionsState.setGlobalGids(mGlobalGids);
713
714        synchronized (mLock) {
715            final int N = pkg.requestedPermissions.size();
716            for (int i = 0; i < N; i++) {
717                final String permName = pkg.requestedPermissions.get(i);
718                final BasePermission bp = mSettings.getPermissionLocked(permName);
719                final boolean appSupportsRuntimePermissions =
720                        pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
721
722                if (DEBUG_INSTALL) {
723                    Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
724                }
725
726                if (bp == null || bp.getSourcePackageSetting() == null) {
727                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
728                        if (DEBUG_PERMISSIONS) {
729                            Slog.i(TAG, "Unknown permission " + permName
730                                    + " in package " + pkg.packageName);
731                        }
732                    }
733                    continue;
734                }
735
736                // Limit ephemeral apps to ephemeral allowed permissions.
737                if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
738                    if (DEBUG_PERMISSIONS) {
739                        Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
740                                + " for package " + pkg.packageName);
741                    }
742                    continue;
743                }
744
745                if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
746                    if (DEBUG_PERMISSIONS) {
747                        Log.i(TAG, "Denying runtime-only permission " + bp.getName()
748                                + " for package " + pkg.packageName);
749                    }
750                    continue;
751                }
752
753                final String perm = bp.getName();
754                boolean allowedSig = false;
755                int grant = GRANT_DENIED;
756
757                // Keep track of app op permissions.
758                if (bp.isAppOp()) {
759                    mSettings.addAppOpPackage(perm, pkg.packageName);
760                }
761
762                if (bp.isNormal()) {
763                    // For all apps normal permissions are install time ones.
764                    grant = GRANT_INSTALL;
765                } else if (bp.isRuntime()) {
766                    // If a permission review is required for legacy apps we represent
767                    // their permissions as always granted runtime ones since we need
768                    // to keep the review required permission flag per user while an
769                    // install permission's state is shared across all users.
770                    if (!appSupportsRuntimePermissions && !mSettings.mPermissionReviewRequired) {
771                        // For legacy apps dangerous permissions are install time ones.
772                        grant = GRANT_INSTALL;
773                    } else if (origPermissions.hasInstallPermission(bp.getName())) {
774                        // For legacy apps that became modern, install becomes runtime.
775                        grant = GRANT_UPGRADE;
776                    } else if (isLegacySystemApp) {
777                        // For legacy system apps, install becomes runtime.
778                        // We cannot check hasInstallPermission() for system apps since those
779                        // permissions were granted implicitly and not persisted pre-M.
780                        grant = GRANT_UPGRADE;
781                    } else {
782                        // For modern apps keep runtime permissions unchanged.
783                        grant = GRANT_RUNTIME;
784                    }
785                } else if (bp.isSignature()) {
786                    // For all apps signature permissions are install time ones.
787                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
788                    if (allowedSig) {
789                        grant = GRANT_INSTALL;
790                    }
791                }
792
793                if (DEBUG_PERMISSIONS) {
794                    Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
795                }
796
797                if (grant != GRANT_DENIED) {
798                    if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
799                        // If this is an existing, non-system package, then
800                        // we can't add any new permissions to it.
801                        if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
802                            // Except...  if this is a permission that was added
803                            // to the platform (note: need to only do this when
804                            // updating the platform).
805                            if (!isNewPlatformPermissionForPackage(perm, pkg)) {
806                                grant = GRANT_DENIED;
807                            }
808                        }
809                    }
810
811                    switch (grant) {
812                        case GRANT_INSTALL: {
813                            // Revoke this as runtime permission to handle the case of
814                            // a runtime permission being downgraded to an install one.
815                            // Also in permission review mode we keep dangerous permissions
816                            // for legacy apps
817                            for (int userId : UserManagerService.getInstance().getUserIds()) {
818                                if (origPermissions.getRuntimePermissionState(
819                                        perm, userId) != null) {
820                                    // Revoke the runtime permission and clear the flags.
821                                    origPermissions.revokeRuntimePermission(bp, userId);
822                                    origPermissions.updatePermissionFlags(bp, userId,
823                                          PackageManager.MASK_PERMISSION_FLAGS, 0);
824                                    // If we revoked a permission permission, we have to write.
825                                    updatedUserIds = ArrayUtils.appendInt(
826                                            updatedUserIds, userId);
827                                }
828                            }
829                            // Grant an install permission.
830                            if (permissionsState.grantInstallPermission(bp) !=
831                                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
832                                changedInstallPermission = true;
833                            }
834                        } break;
835
836                        case GRANT_RUNTIME: {
837                            // Grant previously granted runtime permissions.
838                            for (int userId : UserManagerService.getInstance().getUserIds()) {
839                                final PermissionState permissionState = origPermissions
840                                        .getRuntimePermissionState(perm, userId);
841                                int flags = permissionState != null
842                                        ? permissionState.getFlags() : 0;
843                                if (origPermissions.hasRuntimePermission(perm, userId)) {
844                                    // Don't propagate the permission in a permission review
845                                    // mode if the former was revoked, i.e. marked to not
846                                    // propagate on upgrade. Note that in a permission review
847                                    // mode install permissions are represented as constantly
848                                    // granted runtime ones since we need to keep a per user
849                                    // state associated with the permission. Also the revoke
850                                    // on upgrade flag is no longer applicable and is reset.
851                                    final boolean revokeOnUpgrade = (flags & PackageManager
852                                            .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
853                                    if (revokeOnUpgrade) {
854                                        flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
855                                        // Since we changed the flags, we have to write.
856                                        updatedUserIds = ArrayUtils.appendInt(
857                                                updatedUserIds, userId);
858                                    }
859                                    if (!mSettings.mPermissionReviewRequired || !revokeOnUpgrade) {
860                                        if (permissionsState.grantRuntimePermission(bp, userId) ==
861                                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
862                                            // If we cannot put the permission as it was,
863                                            // we have to write.
864                                            updatedUserIds = ArrayUtils.appendInt(
865                                                    updatedUserIds, userId);
866                                        }
867                                    }
868
869                                    // If the app supports runtime permissions no need for a review.
870                                    if (mSettings.mPermissionReviewRequired
871                                            && appSupportsRuntimePermissions
872                                            && (flags & PackageManager
873                                                    .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
874                                        flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
875                                        // Since we changed the flags, we have to write.
876                                        updatedUserIds = ArrayUtils.appendInt(
877                                                updatedUserIds, userId);
878                                    }
879                                } else if (mSettings.mPermissionReviewRequired
880                                        && !appSupportsRuntimePermissions) {
881                                    // For legacy apps that need a permission review, every new
882                                    // runtime permission is granted but it is pending a review.
883                                    // We also need to review only platform defined runtime
884                                    // permissions as these are the only ones the platform knows
885                                    // how to disable the API to simulate revocation as legacy
886                                    // apps don't expect to run with revoked permissions.
887                                    if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
888                                        if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
889                                            flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
890                                            // We changed the flags, hence have to write.
891                                            updatedUserIds = ArrayUtils.appendInt(
892                                                    updatedUserIds, userId);
893                                        }
894                                    }
895                                    if (permissionsState.grantRuntimePermission(bp, userId)
896                                            != PermissionsState.PERMISSION_OPERATION_FAILURE) {
897                                        // We changed the permission, hence have to write.
898                                        updatedUserIds = ArrayUtils.appendInt(
899                                                updatedUserIds, userId);
900                                    }
901                                }
902                                // Propagate the permission flags.
903                                permissionsState.updatePermissionFlags(bp, userId, flags, flags);
904                            }
905                        } break;
906
907                        case GRANT_UPGRADE: {
908                            // Grant runtime permissions for a previously held install permission.
909                            final PermissionState permissionState = origPermissions
910                                    .getInstallPermissionState(perm);
911                            final int flags =
912                                    (permissionState != null) ? permissionState.getFlags() : 0;
913
914                            if (origPermissions.revokeInstallPermission(bp)
915                                    != PermissionsState.PERMISSION_OPERATION_FAILURE) {
916                                // We will be transferring the permission flags, so clear them.
917                                origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
918                                        PackageManager.MASK_PERMISSION_FLAGS, 0);
919                                changedInstallPermission = true;
920                            }
921
922                            // If the permission is not to be promoted to runtime we ignore it and
923                            // also its other flags as they are not applicable to install permissions.
924                            if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
925                                for (int userId : currentUserIds) {
926                                    if (permissionsState.grantRuntimePermission(bp, userId) !=
927                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
928                                        // Transfer the permission flags.
929                                        permissionsState.updatePermissionFlags(bp, userId,
930                                                flags, flags);
931                                        // If we granted the permission, we have to write.
932                                        updatedUserIds = ArrayUtils.appendInt(
933                                                updatedUserIds, userId);
934                                    }
935                                }
936                            }
937                        } break;
938
939                        default: {
940                            if (packageOfInterest == null
941                                    || packageOfInterest.equals(pkg.packageName)) {
942                                if (DEBUG_PERMISSIONS) {
943                                    Slog.i(TAG, "Not granting permission " + perm
944                                            + " to package " + pkg.packageName
945                                            + " because it was previously installed without");
946                                }
947                            }
948                        } break;
949                    }
950                } else {
951                    if (permissionsState.revokeInstallPermission(bp) !=
952                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
953                        // Also drop the permission flags.
954                        permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
955                                PackageManager.MASK_PERMISSION_FLAGS, 0);
956                        changedInstallPermission = true;
957                        Slog.i(TAG, "Un-granting permission " + perm
958                                + " from package " + pkg.packageName
959                                + " (protectionLevel=" + bp.getProtectionLevel()
960                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
961                                + ")");
962                    } else if (bp.isAppOp()) {
963                        // Don't print warning for app op permissions, since it is fine for them
964                        // not to be granted, there is a UI for the user to decide.
965                        if (DEBUG_PERMISSIONS
966                                && (packageOfInterest == null
967                                        || packageOfInterest.equals(pkg.packageName))) {
968                            Slog.i(TAG, "Not granting permission " + perm
969                                    + " to package " + pkg.packageName
970                                    + " (protectionLevel=" + bp.getProtectionLevel()
971                                    + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
972                                    + ")");
973                        }
974                    }
975                }
976            }
977
978            if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
979                    !ps.isSystem() || ps.isUpdatedSystem()) {
980                // This is the first that we have heard about this package, so the
981                // permissions we have now selected are fixed until explicitly
982                // changed.
983                ps.setInstallPermissionsFixed(true);
984            }
985        }
986
987        // Persist the runtime permissions state for users with changes. If permissions
988        // were revoked because no app in the shared user declares them we have to
989        // write synchronously to avoid losing runtime permissions state.
990        if (callback != null) {
991            callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
992        }
993    }
994
995    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
996        boolean allowed = false;
997        final int NP = PackageParser.NEW_PERMISSIONS.length;
998        for (int ip=0; ip<NP; ip++) {
999            final PackageParser.NewPermissionInfo npi
1000                    = PackageParser.NEW_PERMISSIONS[ip];
1001            if (npi.name.equals(perm)
1002                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1003                allowed = true;
1004                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1005                        + pkg.packageName);
1006                break;
1007            }
1008        }
1009        return allowed;
1010    }
1011
1012    /**
1013     * Determines whether a package is whitelisted for a particular privapp permission.
1014     *
1015     * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1016     *
1017     * <p>This handles parent/child apps.
1018     */
1019    private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
1020        ArraySet<String> wlPermissions = null;
1021        if (pkg.isVendor()) {
1022            wlPermissions =
1023                    SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1024        } else if (pkg.isProduct()) {
1025            wlPermissions =
1026                    SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
1027        } else {
1028            wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1029        }
1030        // Let's check if this package is whitelisted...
1031        boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1032        // If it's not, we'll also tail-recurse to the parent.
1033        return whitelisted ||
1034                pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1035    }
1036
1037    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1038            BasePermission bp, PermissionsState origPermissions) {
1039        boolean oemPermission = bp.isOEM();
1040        boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1041        boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
1042        boolean privappPermissionsDisable =
1043                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1044        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1045        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1046        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1047                && !platformPackage && platformPermission) {
1048            if (!hasPrivappWhitelistEntry(perm, pkg)) {
1049                // Only report violations for apps on system image
1050                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1051                    // it's only a reportable violation if the permission isn't explicitly denied
1052                    ArraySet<String> deniedPermissions = null;
1053                    if (pkg.isVendor()) {
1054                        deniedPermissions = SystemConfig.getInstance()
1055                                .getVendorPrivAppDenyPermissions(pkg.packageName);
1056                    } else if (pkg.isProduct()) {
1057                        deniedPermissions = SystemConfig.getInstance()
1058                                .getProductPrivAppDenyPermissions(pkg.packageName);
1059                    } else {
1060                        deniedPermissions = SystemConfig.getInstance()
1061                                .getPrivAppDenyPermissions(pkg.packageName);
1062                    }
1063                    final boolean permissionViolation =
1064                            deniedPermissions == null || !deniedPermissions.contains(perm);
1065                    if (permissionViolation) {
1066                        Slog.w(TAG, "Privileged permission " + perm + " for package "
1067                                + pkg.packageName + " - not in privapp-permissions whitelist");
1068
1069                        if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1070                            if (mPrivappPermissionsViolations == null) {
1071                                mPrivappPermissionsViolations = new ArraySet<>();
1072                            }
1073                            mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
1074                        }
1075                    } else {
1076                        return false;
1077                    }
1078                }
1079                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1080                    return false;
1081                }
1082            }
1083        }
1084        final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1085                PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1086        final PackageParser.Package systemPackage =
1087                mPackageManagerInt.getPackage(systemPackageName);
1088
1089        // check if the package is allow to use this signature permission.  A package is allowed to
1090        // use a signature permission if:
1091        //     - it has the same set of signing certificates as the source package
1092        //     - or its signing certificate was rotated from the source package's certificate
1093        //     - or its signing certificate is a previous signing certificate of the defining
1094        //       package, and the defining package still trusts the old certificate for permissions
1095        //     - or it shares the above relationships with the system package
1096        boolean allowed =
1097                pkg.mSigningDetails.hasAncestorOrSelf(
1098                        bp.getSourcePackageSetting().getSigningDetails())
1099                || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1100                        pkg.mSigningDetails,
1101                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1102                || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1103                || systemPackage.mSigningDetails.checkCapability(
1104                        pkg.mSigningDetails,
1105                        PackageParser.SigningDetails.CertCapabilities.PERMISSION);
1106        if (!allowed && (privilegedPermission || oemPermission)) {
1107            if (pkg.isSystem()) {
1108                // For updated system applications, a privileged/oem permission
1109                // is granted only if it had been defined by the original application.
1110                if (pkg.isUpdatedSystemApp()) {
1111                    final PackageParser.Package disabledPkg =
1112                            mPackageManagerInt.getDisabledPackage(pkg.packageName);
1113                    final PackageSetting disabledPs =
1114                            (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1115                    if (disabledPs != null
1116                            && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1117                        // If the original was granted this permission, we take
1118                        // that grant decision as read and propagate it to the
1119                        // update.
1120                        if ((privilegedPermission && disabledPs.isPrivileged())
1121                                || (oemPermission && disabledPs.isOem()
1122                                        && canGrantOemPermission(disabledPs, perm))) {
1123                            allowed = true;
1124                        }
1125                    } else {
1126                        // The system apk may have been updated with an older
1127                        // version of the one on the data partition, but which
1128                        // granted a new system permission that it didn't have
1129                        // before.  In this case we do want to allow the app to
1130                        // now get the new permission if the ancestral apk is
1131                        // privileged to get it.
1132                        if (disabledPs != null && disabledPkg != null
1133                                && isPackageRequestingPermission(disabledPkg, perm)
1134                                && ((privilegedPermission && disabledPs.isPrivileged())
1135                                        || (oemPermission && disabledPs.isOem()
1136                                                && canGrantOemPermission(disabledPs, perm)))) {
1137                            allowed = true;
1138                        }
1139                        // Also if a privileged parent package on the system image or any of
1140                        // its children requested a privileged/oem permission, the updated child
1141                        // packages can also get the permission.
1142                        if (pkg.parentPackage != null) {
1143                            final PackageParser.Package disabledParentPkg = mPackageManagerInt
1144                                    .getDisabledPackage(pkg.parentPackage.packageName);
1145                            final PackageSetting disabledParentPs = (disabledParentPkg != null)
1146                                    ? (PackageSetting) disabledParentPkg.mExtras : null;
1147                            if (disabledParentPkg != null
1148                                    && ((privilegedPermission && disabledParentPs.isPrivileged())
1149                                            || (oemPermission && disabledParentPs.isOem()))) {
1150                                if (isPackageRequestingPermission(disabledParentPkg, perm)
1151                                        && canGrantOemPermission(disabledParentPs, perm)) {
1152                                    allowed = true;
1153                                } else if (disabledParentPkg.childPackages != null) {
1154                                    for (PackageParser.Package disabledChildPkg
1155                                            : disabledParentPkg.childPackages) {
1156                                        final PackageSetting disabledChildPs =
1157                                                (disabledChildPkg != null)
1158                                                        ? (PackageSetting) disabledChildPkg.mExtras
1159                                                        : null;
1160                                        if (isPackageRequestingPermission(disabledChildPkg, perm)
1161                                                && canGrantOemPermission(
1162                                                        disabledChildPs, perm)) {
1163                                            allowed = true;
1164                                            break;
1165                                        }
1166                                    }
1167                                }
1168                            }
1169                        }
1170                    }
1171                } else {
1172                    final PackageSetting ps = (PackageSetting) pkg.mExtras;
1173                    allowed = (privilegedPermission && pkg.isPrivileged())
1174                            || (oemPermission && pkg.isOem()
1175                                    && canGrantOemPermission(ps, perm));
1176                }
1177                // In any case, don't grant a privileged permission to privileged vendor apps, if
1178                // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1179                // flag.
1180                if (allowed && privilegedPermission &&
1181                        !vendorPrivilegedPermission && pkg.isVendor()) {
1182                   Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1183                           + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1184                   allowed = false;
1185                }
1186            }
1187        }
1188        if (!allowed) {
1189            if (!allowed
1190                    && bp.isPre23()
1191                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1192                // If this was a previously normal/dangerous permission that got moved
1193                // to a system permission as part of the runtime permission redesign, then
1194                // we still want to blindly grant it to old apps.
1195                allowed = true;
1196            }
1197            if (!allowed && bp.isInstaller()
1198                    && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1199                            PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))) {
1200                // If this permission is to be granted to the system installer and
1201                // this app is an installer, then it gets the permission.
1202                allowed = true;
1203            }
1204            if (!allowed && bp.isVerifier()
1205                    && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1206                            PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1207                // If this permission is to be granted to the system verifier and
1208                // this app is a verifier, then it gets the permission.
1209                allowed = true;
1210            }
1211            if (!allowed && bp.isPreInstalled()
1212                    && pkg.isSystem()) {
1213                // Any pre-installed system app is allowed to get this permission.
1214                allowed = true;
1215            }
1216            if (!allowed && bp.isDevelopment()) {
1217                // For development permissions, a development permission
1218                // is granted only if it was already granted.
1219                allowed = origPermissions.hasInstallPermission(perm);
1220            }
1221            if (!allowed && bp.isSetup()
1222                    && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1223                            PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1224                // If this permission is to be granted to the system setup wizard and
1225                // this app is a setup wizard, then it gets the permission.
1226                allowed = true;
1227            }
1228            if (!allowed && bp.isSystemTextClassifier()
1229                    && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1230                            PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1231                            UserHandle.USER_SYSTEM))) {
1232                // Special permissions for the system default text classifier.
1233                allowed = true;
1234            }
1235        }
1236        return allowed;
1237    }
1238
1239    private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1240        if (!ps.isOem()) {
1241            return false;
1242        }
1243        // all oem permissions must explicitly be granted or denied
1244        final Boolean granted =
1245                SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1246        if (granted == null) {
1247            throw new IllegalStateException("OEM permission" + permission + " requested by package "
1248                    + ps.name + " must be explicitly declared granted or not");
1249        }
1250        return Boolean.TRUE == granted;
1251    }
1252
1253    private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
1254        if (!mSettings.mPermissionReviewRequired) {
1255            return false;
1256        }
1257
1258        // Permission review applies only to apps not supporting the new permission model.
1259        if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1260            return false;
1261        }
1262
1263        // Legacy apps have the permission and get user consent on launch.
1264        if (pkg == null || pkg.mExtras == null) {
1265            return false;
1266        }
1267        final PackageSetting ps = (PackageSetting) pkg.mExtras;
1268        final PermissionsState permissionsState = ps.getPermissionsState();
1269        return permissionsState.isPermissionReviewRequired(userId);
1270    }
1271
1272    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1273        final int permCount = pkg.requestedPermissions.size();
1274        for (int j = 0; j < permCount; j++) {
1275            String requestedPermission = pkg.requestedPermissions.get(j);
1276            if (permission.equals(requestedPermission)) {
1277                return true;
1278            }
1279        }
1280        return false;
1281    }
1282
1283    @GuardedBy("mLock")
1284    private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1285            PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1286        if (pkg.parentPackage == null) {
1287            return;
1288        }
1289        if (pkg.requestedPermissions == null) {
1290            return;
1291        }
1292        final PackageParser.Package disabledPkg =
1293                mPackageManagerInt.getDisabledPackage(pkg.parentPackage.packageName);
1294        if (disabledPkg == null || disabledPkg.mExtras == null) {
1295            return;
1296        }
1297        final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1298        if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1299            return;
1300        }
1301        final int permCount = pkg.requestedPermissions.size();
1302        for (int i = 0; i < permCount; i++) {
1303            String permission = pkg.requestedPermissions.get(i);
1304            BasePermission bp = mSettings.getPermissionLocked(permission);
1305            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1306                continue;
1307            }
1308            for (int userId : mUserManagerInt.getUserIds()) {
1309                if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1310                    grantRuntimePermission(
1311                            permission, pkg.packageName, false, callingUid, userId, callback);
1312                }
1313            }
1314        }
1315    }
1316
1317    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1318            String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1319        for (int userId : userIds) {
1320            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1321                    callback);
1322        }
1323    }
1324
1325    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1326            String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1327        PackageSetting ps = (PackageSetting) pkg.mExtras;
1328        if (ps == null) {
1329            return;
1330        }
1331
1332        PermissionsState permissionsState = ps.getPermissionsState();
1333
1334        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1335                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1336
1337        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1338                >= Build.VERSION_CODES.M;
1339
1340        final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1341
1342        for (String permission : pkg.requestedPermissions) {
1343            final BasePermission bp;
1344            synchronized (mLock) {
1345                bp = mSettings.getPermissionLocked(permission);
1346            }
1347            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1348                    && (!instantApp || bp.isInstant())
1349                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1350                    && (grantedPermissions == null
1351                           || ArrayUtils.contains(grantedPermissions, permission))) {
1352                final int flags = permissionsState.getPermissionFlags(permission, userId);
1353                if (supportsRuntimePermissions) {
1354                    // Installer cannot change immutable permissions.
1355                    if ((flags & immutableFlags) == 0) {
1356                        grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1357                                userId, callback);
1358                    }
1359                } else if (mSettings.mPermissionReviewRequired) {
1360                    // In permission review mode we clear the review flag when we
1361                    // are asked to install the app with all permissions granted.
1362                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1363                        updatePermissionFlags(permission, pkg.packageName,
1364                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
1365                                userId, callback);
1366                    }
1367                }
1368            }
1369        }
1370    }
1371
1372    private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1373            int callingUid, final int userId, PermissionCallback callback) {
1374        if (!mUserManagerInt.exists(userId)) {
1375            Log.e(TAG, "No such user:" + userId);
1376            return;
1377        }
1378
1379        mContext.enforceCallingOrSelfPermission(
1380                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1381                "grantRuntimePermission");
1382
1383        enforceCrossUserPermission(callingUid, userId,
1384                true,  // requireFullPermission
1385                true,  // checkShell
1386                false, // requirePermissionWhenSameUser
1387                "grantRuntimePermission");
1388
1389        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1390        if (pkg == null || pkg.mExtras == null) {
1391            throw new IllegalArgumentException("Unknown package: " + packageName);
1392        }
1393        final BasePermission bp;
1394        synchronized(mLock) {
1395            bp = mSettings.getPermissionLocked(permName);
1396        }
1397        if (bp == null) {
1398            throw new IllegalArgumentException("Unknown permission: " + permName);
1399        }
1400        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1401            throw new IllegalArgumentException("Unknown package: " + packageName);
1402        }
1403
1404        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1405
1406        // If a permission review is required for legacy apps we represent
1407        // their permissions as always granted runtime ones since we need
1408        // to keep the review required permission flag per user while an
1409        // install permission's state is shared across all users.
1410        if (mSettings.mPermissionReviewRequired
1411                && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1412                && bp.isRuntime()) {
1413            return;
1414        }
1415
1416        final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1417
1418        final PackageSetting ps = (PackageSetting) pkg.mExtras;
1419        final PermissionsState permissionsState = ps.getPermissionsState();
1420
1421        final int flags = permissionsState.getPermissionFlags(permName, userId);
1422        if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1423            throw new SecurityException("Cannot grant system fixed permission "
1424                    + permName + " for package " + packageName);
1425        }
1426        if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1427            throw new SecurityException("Cannot grant policy fixed permission "
1428                    + permName + " for package " + packageName);
1429        }
1430
1431        if (bp.isDevelopment()) {
1432            // Development permissions must be handled specially, since they are not
1433            // normal runtime permissions.  For now they apply to all users.
1434            if (permissionsState.grantInstallPermission(bp) !=
1435                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
1436                if (callback != null) {
1437                    callback.onInstallPermissionGranted();
1438                }
1439            }
1440            return;
1441        }
1442
1443        if (ps.getInstantApp(userId) && !bp.isInstant()) {
1444            throw new SecurityException("Cannot grant non-ephemeral permission"
1445                    + permName + " for package " + packageName);
1446        }
1447
1448        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1449            Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1450            return;
1451        }
1452
1453        final int result = permissionsState.grantRuntimePermission(bp, userId);
1454        switch (result) {
1455            case PermissionsState.PERMISSION_OPERATION_FAILURE: {
1456                return;
1457            }
1458
1459            case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1460                if (callback != null) {
1461                    callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1462                }
1463            }
1464            break;
1465        }
1466
1467        if (bp.isRuntime()) {
1468            logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
1469        }
1470
1471        if (callback != null) {
1472            callback.onPermissionGranted(uid, userId);
1473        }
1474
1475        // Only need to do this if user is initialized. Otherwise it's a new user
1476        // and there are no processes running as the user yet and there's no need
1477        // to make an expensive call to remount processes for the changed permissions.
1478        if (READ_EXTERNAL_STORAGE.equals(permName)
1479                || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1480            final long token = Binder.clearCallingIdentity();
1481            try {
1482                if (mUserManagerInt.isUserInitialized(userId)) {
1483                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
1484                            StorageManagerInternal.class);
1485                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1486                }
1487            } finally {
1488                Binder.restoreCallingIdentity(token);
1489            }
1490        }
1491
1492    }
1493
1494    private void revokeRuntimePermission(String permName, String packageName,
1495            boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
1496        if (!mUserManagerInt.exists(userId)) {
1497            Log.e(TAG, "No such user:" + userId);
1498            return;
1499        }
1500
1501        mContext.enforceCallingOrSelfPermission(
1502                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1503                "revokeRuntimePermission");
1504
1505        enforceCrossUserPermission(Binder.getCallingUid(), userId,
1506                true,  // requireFullPermission
1507                true,  // checkShell
1508                false, // requirePermissionWhenSameUser
1509                "revokeRuntimePermission");
1510
1511        final int appId;
1512
1513        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1514        if (pkg == null || pkg.mExtras == null) {
1515            throw new IllegalArgumentException("Unknown package: " + packageName);
1516        }
1517        if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
1518            throw new IllegalArgumentException("Unknown package: " + packageName);
1519        }
1520        final BasePermission bp = mSettings.getPermissionLocked(permName);
1521        if (bp == null) {
1522            throw new IllegalArgumentException("Unknown permission: " + permName);
1523        }
1524
1525        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1526
1527        // If a permission review is required for legacy apps we represent
1528        // their permissions as always granted runtime ones since we need
1529        // to keep the review required permission flag per user while an
1530        // install permission's state is shared across all users.
1531        if (mSettings.mPermissionReviewRequired
1532                && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1533                && bp.isRuntime()) {
1534            return;
1535        }
1536
1537        final PackageSetting ps = (PackageSetting) pkg.mExtras;
1538        final PermissionsState permissionsState = ps.getPermissionsState();
1539
1540        final int flags = permissionsState.getPermissionFlags(permName, userId);
1541        // Only the system may revoke SYSTEM_FIXED permissions.
1542        if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1543                && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1544            throw new SecurityException("Non-System UID cannot revoke system fixed permission "
1545                    + permName + " for package " + packageName);
1546        }
1547        if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1548            throw new SecurityException("Cannot revoke policy fixed permission "
1549                    + permName + " for package " + packageName);
1550        }
1551
1552        if (bp.isDevelopment()) {
1553            // Development permissions must be handled specially, since they are not
1554            // normal runtime permissions.  For now they apply to all users.
1555            if (permissionsState.revokeInstallPermission(bp) !=
1556                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
1557                if (callback != null) {
1558                    callback.onInstallPermissionRevoked();
1559                }
1560            }
1561            return;
1562        }
1563
1564        if (permissionsState.revokeRuntimePermission(bp, userId) ==
1565                PermissionsState.PERMISSION_OPERATION_FAILURE) {
1566            return;
1567        }
1568
1569        if (bp.isRuntime()) {
1570            logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
1571        }
1572
1573        if (callback != null) {
1574            final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1575            callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1576        }
1577    }
1578
1579    @GuardedBy("mLock")
1580    private int[] revokeUnusedSharedUserPermissionsLocked(
1581            SharedUserSetting suSetting, int[] allUserIds) {
1582        // Collect all used permissions in the UID
1583        final ArraySet<String> usedPermissions = new ArraySet<>();
1584        final List<PackageParser.Package> pkgList = suSetting.getPackages();
1585        if (pkgList == null || pkgList.size() == 0) {
1586            return EmptyArray.INT;
1587        }
1588        for (PackageParser.Package pkg : pkgList) {
1589            if (pkg.requestedPermissions == null) {
1590                continue;
1591            }
1592            final int requestedPermCount = pkg.requestedPermissions.size();
1593            for (int j = 0; j < requestedPermCount; j++) {
1594                String permission = pkg.requestedPermissions.get(j);
1595                BasePermission bp = mSettings.getPermissionLocked(permission);
1596                if (bp != null) {
1597                    usedPermissions.add(permission);
1598                }
1599            }
1600        }
1601
1602        PermissionsState permissionsState = suSetting.getPermissionsState();
1603        // Prune install permissions
1604        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
1605        final int installPermCount = installPermStates.size();
1606        for (int i = installPermCount - 1; i >= 0;  i--) {
1607            PermissionState permissionState = installPermStates.get(i);
1608            if (!usedPermissions.contains(permissionState.getName())) {
1609                BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1610                if (bp != null) {
1611                    permissionsState.revokeInstallPermission(bp);
1612                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1613                            PackageManager.MASK_PERMISSION_FLAGS, 0);
1614                }
1615            }
1616        }
1617
1618        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
1619
1620        // Prune runtime permissions
1621        for (int userId : allUserIds) {
1622            List<PermissionState> runtimePermStates = permissionsState
1623                    .getRuntimePermissionStates(userId);
1624            final int runtimePermCount = runtimePermStates.size();
1625            for (int i = runtimePermCount - 1; i >= 0; i--) {
1626                PermissionState permissionState = runtimePermStates.get(i);
1627                if (!usedPermissions.contains(permissionState.getName())) {
1628                    BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1629                    if (bp != null) {
1630                        permissionsState.revokeRuntimePermission(bp, userId);
1631                        permissionsState.updatePermissionFlags(bp, userId,
1632                                PackageManager.MASK_PERMISSION_FLAGS, 0);
1633                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
1634                                runtimePermissionChangedUserIds, userId);
1635                    }
1636                }
1637            }
1638        }
1639
1640        return runtimePermissionChangedUserIds;
1641    }
1642
1643    private String[] getAppOpPermissionPackages(String permName) {
1644        if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1645            return null;
1646        }
1647        synchronized (mLock) {
1648            final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
1649            if (pkgs == null) {
1650                return null;
1651            }
1652            return pkgs.toArray(new String[pkgs.size()]);
1653        }
1654    }
1655
1656    private int getPermissionFlags(
1657            String permName, String packageName, int callingUid, int userId) {
1658        if (!mUserManagerInt.exists(userId)) {
1659            return 0;
1660        }
1661
1662        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
1663
1664        enforceCrossUserPermission(callingUid, userId,
1665                true,  // requireFullPermission
1666                false, // checkShell
1667                false, // requirePermissionWhenSameUser
1668                "getPermissionFlags");
1669
1670        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1671        if (pkg == null || pkg.mExtras == null) {
1672            return 0;
1673        }
1674        synchronized (mLock) {
1675            if (mSettings.getPermissionLocked(permName) == null) {
1676                return 0;
1677            }
1678        }
1679        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1680            return 0;
1681        }
1682        final PackageSetting ps = (PackageSetting) pkg.mExtras;
1683        PermissionsState permissionsState = ps.getPermissionsState();
1684        return permissionsState.getPermissionFlags(permName, userId);
1685    }
1686
1687    private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
1688    private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
1689    private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
1690
1691    private void updatePermissions(String packageName, PackageParser.Package pkg,
1692            boolean replaceGrant, Collection<PackageParser.Package> allPackages,
1693            PermissionCallback callback) {
1694        final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
1695                (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
1696        updatePermissions(
1697                packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
1698        if (pkg != null && pkg.childPackages != null) {
1699            for (PackageParser.Package childPkg : pkg.childPackages) {
1700                updatePermissions(childPkg.packageName, childPkg,
1701                        getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
1702            }
1703        }
1704    }
1705
1706    private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
1707            Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
1708        final int flags = UPDATE_PERMISSIONS_ALL |
1709                (sdkUpdated
1710                        ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
1711                        : 0);
1712        updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
1713    }
1714
1715    private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
1716            String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
1717            PermissionCallback callback) {
1718        // TODO: Most of the methods exposing BasePermission internals [source package name,
1719        // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
1720        // have package settings, we should make note of it elsewhere [map between
1721        // source package name and BasePermission] and cycle through that here. Then we
1722        // define a single method on BasePermission that takes a PackageSetting, changing
1723        // package name and a package.
1724        // NOTE: With this approach, we also don't need to tree trees differently than
1725        // normal permissions. Today, we need two separate loops because these BasePermission
1726        // objects are stored separately.
1727        // Make sure there are no dangling permission trees.
1728        flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
1729
1730        // Make sure all dynamic permissions have been assigned to a package,
1731        // and make sure there are no dangling permissions.
1732        flags = updatePermissions(changingPkgName, changingPkg, flags);
1733
1734        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
1735        // Now update the permissions for all packages, in particular
1736        // replace the granted permissions of the system packages.
1737        if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
1738            for (PackageParser.Package pkg : allPackages) {
1739                if (pkg != changingPkg) {
1740                    // Only replace for packages on requested volume
1741                    final String volumeUuid = getVolumeUuidForPackage(pkg);
1742                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
1743                            && Objects.equals(replaceVolumeUuid, volumeUuid);
1744                    grantPermissions(pkg, replace, changingPkgName, callback);
1745                }
1746            }
1747        }
1748
1749        if (changingPkg != null) {
1750            // Only replace for packages on requested volume
1751            final String volumeUuid = getVolumeUuidForPackage(changingPkg);
1752            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
1753                    && Objects.equals(replaceVolumeUuid, volumeUuid);
1754            grantPermissions(changingPkg, replace, changingPkgName, callback);
1755        }
1756        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1757    }
1758
1759    private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
1760        Set<BasePermission> needsUpdate = null;
1761        synchronized (mLock) {
1762            final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
1763            while (it.hasNext()) {
1764                final BasePermission bp = it.next();
1765                if (bp.isDynamic()) {
1766                    bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
1767                }
1768                if (bp.getSourcePackageSetting() != null) {
1769                    if (packageName != null && packageName.equals(bp.getSourcePackageName())
1770                        && (pkg == null || !hasPermission(pkg, bp.getName()))) {
1771                        Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1772                                + " from package " + bp.getSourcePackageName());
1773                        flags |= UPDATE_PERMISSIONS_ALL;
1774                        it.remove();
1775                    }
1776                    continue;
1777                }
1778                if (needsUpdate == null) {
1779                    needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
1780                }
1781                needsUpdate.add(bp);
1782            }
1783        }
1784        if (needsUpdate != null) {
1785            for (final BasePermission bp : needsUpdate) {
1786                final PackageParser.Package sourcePkg =
1787                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
1788                synchronized (mLock) {
1789                    if (sourcePkg != null && sourcePkg.mExtras != null) {
1790                        final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
1791                        if (bp.getSourcePackageSetting() == null) {
1792                            bp.setSourcePackageSetting(sourcePs);
1793                        }
1794                        continue;
1795                    }
1796                    Slog.w(TAG, "Removing dangling permission: " + bp.getName()
1797                            + " from package " + bp.getSourcePackageName());
1798                    mSettings.removePermissionLocked(bp.getName());
1799                }
1800            }
1801        }
1802        return flags;
1803    }
1804
1805    private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
1806            int flags) {
1807        Set<BasePermission> needsUpdate = null;
1808        synchronized (mLock) {
1809            final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
1810            while (it.hasNext()) {
1811                final BasePermission bp = it.next();
1812                if (bp.getSourcePackageSetting() != null) {
1813                    if (packageName != null && packageName.equals(bp.getSourcePackageName())
1814                        && (pkg == null || !hasPermission(pkg, bp.getName()))) {
1815                        Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1816                                + " from package " + bp.getSourcePackageName());
1817                        flags |= UPDATE_PERMISSIONS_ALL;
1818                        it.remove();
1819                    }
1820                    continue;
1821                }
1822                if (needsUpdate == null) {
1823                    needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
1824                }
1825                needsUpdate.add(bp);
1826            }
1827        }
1828        if (needsUpdate != null) {
1829            for (final BasePermission bp : needsUpdate) {
1830                final PackageParser.Package sourcePkg =
1831                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
1832                synchronized (mLock) {
1833                    if (sourcePkg != null && sourcePkg.mExtras != null) {
1834                        final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
1835                        if (bp.getSourcePackageSetting() == null) {
1836                            bp.setSourcePackageSetting(sourcePs);
1837                        }
1838                        continue;
1839                    }
1840                    Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
1841                            + " from package " + bp.getSourcePackageName());
1842                    mSettings.removePermissionLocked(bp.getName());
1843                }
1844            }
1845        }
1846        return flags;
1847    }
1848
1849    private void updatePermissionFlags(String permName, String packageName, int flagMask,
1850            int flagValues, int callingUid, int userId, PermissionCallback callback) {
1851        if (!mUserManagerInt.exists(userId)) {
1852            return;
1853        }
1854
1855        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
1856
1857        enforceCrossUserPermission(callingUid, userId,
1858                true,  // requireFullPermission
1859                true,  // checkShell
1860                false, // requirePermissionWhenSameUser
1861                "updatePermissionFlags");
1862
1863        // Only the system can change these flags and nothing else.
1864        if (callingUid != Process.SYSTEM_UID) {
1865            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1866            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1867            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1868            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1869            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
1870        }
1871
1872        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1873        if (pkg == null || pkg.mExtras == null) {
1874            throw new IllegalArgumentException("Unknown package: " + packageName);
1875        }
1876        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1877            throw new IllegalArgumentException("Unknown package: " + packageName);
1878        }
1879
1880        final BasePermission bp;
1881        synchronized (mLock) {
1882            bp = mSettings.getPermissionLocked(permName);
1883        }
1884        if (bp == null) {
1885            throw new IllegalArgumentException("Unknown permission: " + permName);
1886        }
1887
1888        final PackageSetting ps = (PackageSetting) pkg.mExtras;
1889        final PermissionsState permissionsState = ps.getPermissionsState();
1890        final boolean hadState =
1891                permissionsState.getRuntimePermissionState(permName, userId) != null;
1892        final boolean permissionUpdated =
1893                permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
1894        if (permissionUpdated && callback != null) {
1895            // Install and runtime permissions are stored in different places,
1896            // so figure out what permission changed and persist the change.
1897            if (permissionsState.getInstallPermissionState(permName) != null) {
1898                callback.onInstallPermissionUpdated();
1899            } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
1900                    || hadState) {
1901                callback.onPermissionUpdated(new int[] { userId }, false);
1902            }
1903        }
1904    }
1905
1906    private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
1907            int userId, Collection<Package> packages, PermissionCallback callback) {
1908        if (!mUserManagerInt.exists(userId)) {
1909            return false;
1910        }
1911
1912        enforceGrantRevokeRuntimePermissionPermissions(
1913                "updatePermissionFlagsForAllApps");
1914        enforceCrossUserPermission(callingUid, userId,
1915                true,  // requireFullPermission
1916                true,  // checkShell
1917                false, // requirePermissionWhenSameUser
1918                "updatePermissionFlagsForAllApps");
1919
1920        // Only the system can change system fixed flags.
1921        if (callingUid != Process.SYSTEM_UID) {
1922            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1923            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1924        }
1925
1926        boolean changed = false;
1927        for (PackageParser.Package pkg : packages) {
1928            final PackageSetting ps = (PackageSetting) pkg.mExtras;
1929            if (ps == null) {
1930                continue;
1931            }
1932            PermissionsState permissionsState = ps.getPermissionsState();
1933            changed |= permissionsState.updatePermissionFlagsForAllPermissions(
1934                    userId, flagMask, flagValues);
1935        }
1936        return changed;
1937    }
1938
1939    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
1940        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
1941                != PackageManager.PERMISSION_GRANTED
1942            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
1943                != PackageManager.PERMISSION_GRANTED) {
1944            throw new SecurityException(message + " requires "
1945                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
1946                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
1947        }
1948    }
1949
1950    /**
1951     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
1952     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
1953     * @param checkShell whether to prevent shell from access if there's a debugging restriction
1954     * @param message the message to log on security exception
1955     */
1956    private void enforceCrossUserPermission(int callingUid, int userId,
1957            boolean requireFullPermission, boolean checkShell,
1958            boolean requirePermissionWhenSameUser, String message) {
1959        if (userId < 0) {
1960            throw new IllegalArgumentException("Invalid userId " + userId);
1961        }
1962        if (checkShell) {
1963            PackageManagerServiceUtils.enforceShellRestriction(
1964                    UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
1965        }
1966        if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
1967        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
1968            if (requireFullPermission) {
1969                mContext.enforceCallingOrSelfPermission(
1970                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
1971            } else {
1972                try {
1973                    mContext.enforceCallingOrSelfPermission(
1974                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
1975                } catch (SecurityException se) {
1976                    mContext.enforceCallingOrSelfPermission(
1977                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
1978                }
1979            }
1980        }
1981    }
1982
1983    private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
1984        int size = 0;
1985        for (BasePermission perm : mSettings.mPermissions.values()) {
1986            size += tree.calculateFootprint(perm);
1987        }
1988        return size;
1989    }
1990
1991    private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
1992        // We calculate the max size of permissions defined by this uid and throw
1993        // if that plus the size of 'info' would exceed our stated maximum.
1994        if (tree.getUid() != Process.SYSTEM_UID) {
1995            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
1996            if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
1997                throw new SecurityException("Permission tree size cap exceeded");
1998            }
1999        }
2000    }
2001
2002    private void systemReady() {
2003        mSystemReady = true;
2004        if (mPrivappPermissionsViolations != null) {
2005            throw new IllegalStateException("Signature|privileged permissions not in "
2006                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2007        }
2008    }
2009
2010    private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2011        if (pkg == null) {
2012            return StorageManager.UUID_PRIVATE_INTERNAL;
2013        }
2014        if (pkg.isExternal()) {
2015            if (TextUtils.isEmpty(pkg.volumeUuid)) {
2016                return StorageManager.UUID_PRIMARY_PHYSICAL;
2017            } else {
2018                return pkg.volumeUuid;
2019            }
2020        } else {
2021            return StorageManager.UUID_PRIVATE_INTERNAL;
2022        }
2023    }
2024
2025    private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2026        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2027            if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2028                return true;
2029            }
2030        }
2031        return false;
2032    }
2033
2034    /**
2035     * Log that a permission request was granted/revoked.
2036     *
2037     * @param action the action performed
2038     * @param name name of the permission
2039     * @param packageName package permission is for
2040     */
2041    private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2042        final LogMaker log = new LogMaker(action);
2043        log.setPackageName(packageName);
2044        log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
2045
2046        mMetricsLogger.write(log);
2047    }
2048
2049    private class PermissionManagerInternalImpl extends PermissionManagerInternal {
2050        @Override
2051        public void systemReady() {
2052            PermissionManagerService.this.systemReady();
2053        }
2054        @Override
2055        public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2056            return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2057        }
2058        @Override
2059        public void revokeRuntimePermissionsIfGroupChanged(
2060                @NonNull PackageParser.Package newPackage,
2061                @NonNull PackageParser.Package oldPackage,
2062                @NonNull ArrayList<String> allPackageNames,
2063                @NonNull PermissionCallback permissionCallback) {
2064            PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2065                    oldPackage, allPackageNames, permissionCallback);
2066        }
2067        @Override
2068        public void addAllPermissions(Package pkg, boolean chatty) {
2069            PermissionManagerService.this.addAllPermissions(pkg, chatty);
2070        }
2071        @Override
2072        public void addAllPermissionGroups(Package pkg, boolean chatty) {
2073            PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2074        }
2075        @Override
2076        public void removeAllPermissions(Package pkg, boolean chatty) {
2077            PermissionManagerService.this.removeAllPermissions(pkg, chatty);
2078        }
2079        @Override
2080        public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
2081                PermissionCallback callback) {
2082            return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2083        }
2084        @Override
2085        public void removeDynamicPermission(String permName, int callingUid,
2086                PermissionCallback callback) {
2087            PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
2088        }
2089        @Override
2090        public void grantRuntimePermission(String permName, String packageName,
2091                boolean overridePolicy, int callingUid, int userId,
2092                PermissionCallback callback) {
2093            PermissionManagerService.this.grantRuntimePermission(
2094                    permName, packageName, overridePolicy, callingUid, userId, callback);
2095        }
2096        @Override
2097        public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2098                String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2099            PermissionManagerService.this.grantRequestedRuntimePermissions(
2100                    pkg, userIds, grantedPermissions, callingUid, callback);
2101        }
2102        @Override
2103        public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2104                int callingUid, PermissionCallback callback) {
2105            PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2106                    pkg, callingUid, callback);
2107        }
2108        @Override
2109        public void revokeRuntimePermission(String permName, String packageName,
2110                boolean overridePolicy, int callingUid, int userId,
2111                PermissionCallback callback) {
2112            PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
2113                    overridePolicy, callingUid, userId, callback);
2114        }
2115        @Override
2116        public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2117                Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2118            PermissionManagerService.this.updatePermissions(
2119                    packageName, pkg, replaceGrant, allPackages, callback);
2120        }
2121        @Override
2122        public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2123                Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2124            PermissionManagerService.this.updateAllPermissions(
2125                    volumeUuid, sdkUpdated, allPackages, callback);
2126        }
2127        @Override
2128        public String[] getAppOpPermissionPackages(String permName) {
2129            return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2130        }
2131        @Override
2132        public int getPermissionFlags(String permName, String packageName, int callingUid,
2133                int userId) {
2134            return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2135                    callingUid, userId);
2136        }
2137        @Override
2138        public void updatePermissionFlags(String permName, String packageName, int flagMask,
2139                int flagValues, int callingUid, int userId, PermissionCallback callback) {
2140            PermissionManagerService.this.updatePermissionFlags(
2141                    permName, packageName, flagMask, flagValues, callingUid, userId, callback);
2142        }
2143        @Override
2144        public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2145                int userId, Collection<Package> packages, PermissionCallback callback) {
2146            return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2147                    flagMask, flagValues, callingUid, userId, packages, callback);
2148        }
2149        @Override
2150        public void enforceCrossUserPermission(int callingUid, int userId,
2151                boolean requireFullPermission, boolean checkShell, String message) {
2152            PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2153                    requireFullPermission, checkShell, false, message);
2154        }
2155        @Override
2156        public void enforceCrossUserPermission(int callingUid, int userId,
2157                boolean requireFullPermission, boolean checkShell,
2158                boolean requirePermissionWhenSameUser, String message) {
2159            PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2160                    requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
2161        }
2162        @Override
2163        public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2164            PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2165        }
2166        @Override
2167        public int checkPermission(String permName, String packageName, int callingUid,
2168                int userId) {
2169            return PermissionManagerService.this.checkPermission(
2170                    permName, packageName, callingUid, userId);
2171        }
2172        @Override
2173        public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2174                int callingUid) {
2175            return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
2176        }
2177        @Override
2178        public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2179                int callingUid) {
2180            return PermissionManagerService.this.getPermissionGroupInfo(
2181                    groupName, flags, callingUid);
2182        }
2183        @Override
2184        public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2185            return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2186        }
2187        @Override
2188        public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2189                int callingUid) {
2190            return PermissionManagerService.this.getPermissionInfo(
2191                    permName, packageName, flags, callingUid);
2192        }
2193        @Override
2194        public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2195                int callingUid) {
2196            return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2197        }
2198        @Override
2199        public PermissionSettings getPermissionSettings() {
2200            return mSettings;
2201        }
2202        @Override
2203        public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2204            return mDefaultPermissionGrantPolicy;
2205        }
2206        @Override
2207        public BasePermission getPermissionTEMP(String permName) {
2208            synchronized (PermissionManagerService.this.mLock) {
2209                return mSettings.getPermissionLocked(permName);
2210            }
2211        }
2212    }
2213}
2214