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