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