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