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