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