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