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