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