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