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