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