1 /* <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.permission.access.permission 18 19 import android.Manifest 20 import android.app.ActivityManager 21 import android.app.AppOpsManager 22 import android.companion.virtual.VirtualDeviceManager 23 import android.compat.annotation.ChangeId 24 import android.compat.annotation.EnabledAfter 25 import android.content.Context 26 import android.content.pm.PackageInstaller 27 import android.content.pm.PackageManager 28 import android.content.pm.PackageManagerInternal 29 import android.content.pm.PermissionGroupInfo 30 import android.content.pm.PermissionInfo 31 import android.content.pm.permission.SplitPermissionInfoParcelable 32 import android.metrics.LogMaker 33 import android.os.Binder 34 import android.os.Build 35 import android.os.Handler 36 import android.os.HandlerThread 37 import android.os.Looper 38 import android.os.Message 39 import android.os.Process 40 import android.os.RemoteCallbackList 41 import android.os.RemoteException 42 import android.os.ServiceManager 43 import android.os.UserHandle 44 import android.os.UserManager 45 import android.permission.IOnPermissionsChangeListener 46 import android.permission.PermissionControllerManager 47 import android.permission.PermissionManager 48 import android.permission.PermissionManager.PermissionState 49 import android.permission.flags.Flags 50 import android.provider.Settings 51 import android.util.ArrayMap 52 import android.util.ArraySet 53 import android.util.DebugUtils 54 import android.util.IndentingPrintWriter 55 import android.util.IntArray as GrowingIntArray 56 import android.util.Slog 57 import android.util.SparseBooleanArray 58 import com.android.internal.annotations.GuardedBy 59 import com.android.internal.compat.IPlatformCompat 60 import com.android.internal.logging.MetricsLogger 61 import com.android.internal.logging.nano.MetricsProto 62 import com.android.internal.util.DumpUtils 63 import com.android.internal.util.Preconditions 64 import com.android.server.FgThread 65 import com.android.server.LocalManagerRegistry 66 import com.android.server.LocalServices 67 import com.android.server.PermissionThread 68 import com.android.server.ServiceThread 69 import com.android.server.SystemConfig 70 import com.android.server.companion.virtual.VirtualDeviceManagerInternal 71 import com.android.server.permission.access.AccessCheckingService 72 import com.android.server.permission.access.AccessState 73 import com.android.server.permission.access.AppOpUri 74 import com.android.server.permission.access.DevicePermissionUri 75 import com.android.server.permission.access.GetStateScope 76 import com.android.server.permission.access.MutateStateScope 77 import com.android.server.permission.access.PermissionUri 78 import com.android.server.permission.access.UidUri 79 import com.android.server.permission.access.appop.AppIdAppOpPolicy 80 import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports 81 import com.android.server.permission.access.immutable.* // ktlint-disable no-wildcard-imports 82 import com.android.server.permission.access.util.andInv 83 import com.android.server.permission.access.util.hasAnyBit 84 import com.android.server.permission.access.util.hasBits 85 import com.android.server.permission.access.util.withClearedCallingIdentity 86 import com.android.server.pm.KnownPackages 87 import com.android.server.pm.PackageInstallerService 88 import com.android.server.pm.PackageManagerLocal 89 import com.android.server.pm.UserManagerInternal 90 import com.android.server.pm.UserManagerService 91 import com.android.server.pm.permission.LegacyPermission 92 import com.android.server.pm.permission.LegacyPermissionSettings 93 import com.android.server.pm.permission.LegacyPermissionState 94 import com.android.server.pm.permission.Permission as LegacyPermission2 95 import com.android.server.pm.permission.PermissionManagerServiceInterface 96 import com.android.server.pm.permission.PermissionManagerServiceInternal 97 import com.android.server.pm.pkg.AndroidPackage 98 import com.android.server.pm.pkg.PackageState 99 import java.io.FileDescriptor 100 import java.io.PrintWriter 101 import java.util.concurrent.CompletableFuture 102 import java.util.concurrent.ExecutionException 103 import java.util.concurrent.TimeUnit 104 import java.util.concurrent.TimeoutException 105 import libcore.util.EmptyArray 106 107 /** Modern implementation of [PermissionManagerServiceInterface]. */ 108 class PermissionService(private val service: AccessCheckingService) : 109 PermissionManagerServiceInterface { 110 private val policy = 111 service.getSchemePolicy(UidUri.SCHEME, PermissionUri.SCHEME) as AppIdPermissionPolicy 112 113 private val devicePolicy = 114 service.getSchemePolicy(UidUri.SCHEME, DevicePermissionUri.SCHEME) as DevicePermissionPolicy 115 116 private val context = service.context 117 private lateinit var metricsLogger: MetricsLogger 118 private lateinit var packageManagerInternal: PackageManagerInternal 119 private lateinit var packageManagerLocal: PackageManagerLocal 120 private lateinit var platformCompat: IPlatformCompat 121 private lateinit var systemConfig: SystemConfig 122 private lateinit var userManagerInternal: UserManagerInternal 123 private lateinit var userManagerService: UserManagerService 124 125 private lateinit var handlerThread: HandlerThread 126 private lateinit var handler: Handler 127 private lateinit var onPermissionsChangeListeners: OnPermissionsChangeListeners 128 private lateinit var onPermissionFlagsChangedListener: OnPermissionFlagsChangedListener 129 130 private val storageVolumeLock = Any() 131 @GuardedBy("storageVolumeLock") private val mountedStorageVolumes = ArraySet<String?>() 132 @GuardedBy("storageVolumeLock") 133 private val storageVolumePackageNames = ArrayMap<String?, MutableList<String>>() 134 135 private var virtualDeviceManagerInternal: VirtualDeviceManagerInternal? = null 136 137 private lateinit var permissionControllerManager: PermissionControllerManager 138 139 /** 140 * A permission backup might contain apps that are not installed. In this case we delay the 141 * restoration until the app is installed. 142 * 143 * This array (`userId -> noDelayedBackupLeft`) is `true` for all the users where there is **no 144 * more** delayed backup left. 145 */ 146 private val isDelayedPermissionBackupFinished = SparseBooleanArray() 147 148 fun initialize() { 149 metricsLogger = MetricsLogger() 150 packageManagerInternal = LocalServices.getService(PackageManagerInternal::class.java) 151 packageManagerLocal = 152 LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java) 153 platformCompat = 154 IPlatformCompat.Stub.asInterface( 155 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE) 156 ) 157 systemConfig = SystemConfig.getInstance() 158 userManagerInternal = LocalServices.getService(UserManagerInternal::class.java) 159 userManagerService = UserManagerService.getInstance() 160 // The package info cache is the cache for package and permission information. 161 // Disable the package info and package permission caches locally but leave the 162 // checkPermission cache active. 163 PackageManager.invalidatePackageInfoCache() 164 PermissionManager.disablePackageNamePermissionCache() 165 166 handlerThread = 167 ServiceThread(LOG_TAG, Process.THREAD_PRIORITY_BACKGROUND, true).apply { start() } 168 handler = Handler(handlerThread.looper) 169 onPermissionsChangeListeners = OnPermissionsChangeListeners(FgThread.get().looper) 170 onPermissionFlagsChangedListener = OnPermissionFlagsChangedListener() 171 policy.addOnPermissionFlagsChangedListener(onPermissionFlagsChangedListener) 172 devicePolicy.addOnPermissionFlagsChangedListener(onPermissionFlagsChangedListener) 173 } 174 175 override fun getAllPermissionGroups(flags: Int): List<PermissionGroupInfo> { 176 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 177 val callingUid = Binder.getCallingUid() 178 if (snapshot.isUidInstantApp(callingUid)) { 179 return emptyList() 180 } 181 182 val permissionGroups = service.getState { with(policy) { getPermissionGroups() } } 183 184 return permissionGroups.mapNotNullIndexedTo(ArrayList()) { _, _, permissionGroup -> 185 if (snapshot.isPackageVisibleToUid(permissionGroup.packageName, callingUid)) { 186 permissionGroup.generatePermissionGroupInfo(flags) 187 } else { 188 null 189 } 190 } 191 } 192 } 193 194 override fun getPermissionGroupInfo( 195 permissionGroupName: String, 196 flags: Int 197 ): PermissionGroupInfo? { 198 val permissionGroup: PermissionGroupInfo 199 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 200 val callingUid = Binder.getCallingUid() 201 if (snapshot.isUidInstantApp(callingUid)) { 202 return null 203 } 204 205 permissionGroup = 206 service.getState { with(policy) { getPermissionGroups()[permissionGroupName] } } 207 ?: return null 208 209 if (!snapshot.isPackageVisibleToUid(permissionGroup.packageName, callingUid)) { 210 return null 211 } 212 } 213 214 return permissionGroup.generatePermissionGroupInfo(flags) 215 } 216 217 /** 218 * Generate a new [PermissionGroupInfo] from [PermissionGroupInfo] and adjust it accordingly. 219 */ 220 private fun PermissionGroupInfo.generatePermissionGroupInfo(flags: Int): PermissionGroupInfo = 221 @Suppress("DEPRECATION") 222 PermissionGroupInfo(this).apply { 223 if (!flags.hasBits(PackageManager.GET_META_DATA)) { 224 metaData = null 225 } 226 } 227 228 override fun getPermissionInfo( 229 permissionName: String, 230 flags: Int, 231 opPackageName: String 232 ): PermissionInfo? { 233 val permission: Permission 234 val targetSdkVersion: Int 235 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 236 val callingUid = Binder.getCallingUid() 237 if (snapshot.isUidInstantApp(callingUid)) { 238 return null 239 } 240 241 permission = 242 service.getState { with(policy) { getPermissions()[permissionName] } } 243 ?: return null 244 245 if (!snapshot.isPackageVisibleToUid(permission.packageName, callingUid)) { 246 return null 247 } 248 249 val opPackage = snapshot.getPackageState(opPackageName)?.androidPackage 250 targetSdkVersion = 251 when { 252 // System sees all flags. 253 isRootOrSystemOrShellUid(callingUid) -> Build.VERSION_CODES.CUR_DEVELOPMENT 254 opPackage != null -> opPackage.targetSdkVersion 255 else -> Build.VERSION_CODES.CUR_DEVELOPMENT 256 } 257 } 258 259 return permission.generatePermissionInfo(flags, targetSdkVersion) 260 } 261 262 /** Generate a new [PermissionInfo] from [Permission] and adjust it accordingly. */ 263 private fun Permission.generatePermissionInfo( 264 flags: Int, 265 targetSdkVersion: Int = Build.VERSION_CODES.CUR_DEVELOPMENT 266 ): PermissionInfo = 267 @Suppress("DEPRECATION") 268 PermissionInfo(permissionInfo).apply { 269 // All Permission objects are registered so the PermissionInfo generated for it should 270 // also have FLAG_INSTALLED. 271 this.flags = this.flags or PermissionInfo.FLAG_INSTALLED 272 if (!flags.hasBits(PackageManager.GET_META_DATA)) { 273 metaData = null 274 } 275 if (targetSdkVersion < Build.VERSION_CODES.O) { 276 val protection = protection 277 // Signature permission's protection flags are always reported. 278 if (protection != PermissionInfo.PROTECTION_SIGNATURE) { 279 protectionLevel = protection 280 } 281 } 282 } 283 284 override fun queryPermissionsByGroup( 285 permissionGroupName: String?, 286 flags: Int 287 ): List<PermissionInfo>? { 288 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 289 val callingUid = Binder.getCallingUid() 290 if (snapshot.isUidInstantApp(callingUid)) { 291 return null 292 } 293 294 val permissions = 295 service.getState { 296 if (permissionGroupName != null) { 297 val permissionGroup = 298 with(policy) { getPermissionGroups()[permissionGroupName] } 299 ?: return null 300 301 if ( 302 !snapshot.isPackageVisibleToUid(permissionGroup.packageName, callingUid) 303 ) { 304 return null 305 } 306 } 307 308 with(policy) { getPermissions() } 309 } 310 311 return permissions.mapNotNullIndexedTo(ArrayList()) { _, _, permission -> 312 if ( 313 permission.groupName == permissionGroupName && 314 snapshot.isPackageVisibleToUid(permission.packageName, callingUid) 315 ) { 316 permission.generatePermissionInfo(flags) 317 } else { 318 null 319 } 320 } 321 } 322 } 323 324 override fun getAllPermissionsWithProtection(protection: Int): List<PermissionInfo> = 325 getPermissionsWithProtectionOrProtectionFlags { permission -> 326 permission.protection == protection 327 } 328 329 override fun getAllPermissionsWithProtectionFlags(protectionFlags: Int): List<PermissionInfo> = 330 getPermissionsWithProtectionOrProtectionFlags { permission -> 331 permission.protectionFlags.hasBits(protectionFlags) 332 } 333 334 private inline fun getPermissionsWithProtectionOrProtectionFlags( 335 predicate: (Permission) -> Boolean 336 ): List<PermissionInfo> { 337 val permissions = service.getState { with(policy) { getPermissions() } } 338 339 return permissions.mapNotNullIndexedTo(ArrayList()) { _, _, permission -> 340 if (predicate(permission)) { 341 permission.generatePermissionInfo(0) 342 } else { 343 null 344 } 345 } 346 } 347 348 override fun getPermissionGids(permissionName: String, userId: Int): IntArray { 349 val permission = 350 service.getState { with(policy) { getPermissions()[permissionName] } } 351 ?: return EmptyArray.INT 352 return permission.getGidsForUser(userId) 353 } 354 355 override fun getInstalledPermissions(packageName: String): Set<String> { 356 requireNotNull(packageName) { "packageName cannot be null" } 357 358 val permissions = service.getState { with(policy) { getPermissions() } } 359 360 return permissions.mapNotNullIndexedTo(ArraySet()) { _, _, permission -> 361 if (permission.packageName == packageName) { 362 permission.name 363 } else { 364 null 365 } 366 } 367 } 368 369 override fun addPermission(permissionInfo: PermissionInfo, async: Boolean): Boolean { 370 val permissionName = permissionInfo.name 371 requireNotNull(permissionName) { "permissionName cannot be null" } 372 val callingUid = Binder.getCallingUid() 373 if (packageManagerLocal.withUnfilteredSnapshot().use { it.isUidInstantApp(callingUid) }) { 374 throw SecurityException("Instant apps cannot add permissions") 375 } 376 if (permissionInfo.labelRes == 0 && permissionInfo.nonLocalizedLabel == null) { 377 throw SecurityException("Label must be specified in permission") 378 } 379 val oldPermission: Permission? 380 381 service.mutateState { 382 val permissionTree = getAndEnforcePermissionTree(permissionName) 383 enforcePermissionTreeSize(permissionInfo, permissionTree) 384 385 oldPermission = with(policy) { getPermissions()[permissionName] } 386 if (oldPermission != null && !oldPermission.isDynamic) { 387 throw SecurityException( 388 "Not allowed to modify non-dynamic permission $permissionName" 389 ) 390 } 391 392 permissionInfo.packageName = permissionTree.permissionInfo.packageName 393 @Suppress("DEPRECATION") 394 permissionInfo.protectionLevel = 395 PermissionInfo.fixProtectionLevel(permissionInfo.protectionLevel) 396 397 val newPermission = 398 Permission(permissionInfo, true, Permission.TYPE_DYNAMIC, permissionTree.appId) 399 400 with(policy) { addPermission(newPermission, !async) } 401 } 402 403 return oldPermission == null 404 } 405 406 override fun removePermission(permissionName: String) { 407 val callingUid = Binder.getCallingUid() 408 if (packageManagerLocal.withUnfilteredSnapshot().use { it.isUidInstantApp(callingUid) }) { 409 throw SecurityException("Instant applications don't have access to this method") 410 } 411 service.mutateState { 412 getAndEnforcePermissionTree(permissionName) 413 val permission = with(policy) { getPermissions()[permissionName] } ?: return@mutateState 414 415 if (!permission.isDynamic) { 416 // TODO(b/67371907): switch to logging if it fails 417 throw SecurityException( 418 "Not allowed to modify non-dynamic permission $permissionName" 419 ) 420 } 421 422 with(policy) { removePermission(permission) } 423 } 424 } 425 426 private fun GetStateScope.getAndEnforcePermissionTree(permissionName: String): Permission { 427 val callingUid = Binder.getCallingUid() 428 val permissionTree = with(policy) { findPermissionTree(permissionName) } 429 if (permissionTree != null && permissionTree.appId == UserHandle.getAppId(callingUid)) { 430 return permissionTree 431 } 432 433 throw SecurityException( 434 "Calling UID $callingUid is not allowed to add to or remove from the permission tree" 435 ) 436 } 437 438 private fun GetStateScope.enforcePermissionTreeSize( 439 permissionInfo: PermissionInfo, 440 permissionTree: Permission 441 ) { 442 // We calculate the max size of permissions defined by this uid and throw 443 // if that plus the size of 'info' would exceed our stated maximum. 444 if (permissionTree.appId != Process.SYSTEM_UID) { 445 val permissionTreeFootprint = calculatePermissionTreeFootprint(permissionTree) 446 if ( 447 permissionTreeFootprint + permissionInfo.calculateFootprint() > 448 MAX_PERMISSION_TREE_FOOTPRINT 449 ) { 450 throw SecurityException("Permission tree size cap exceeded") 451 } 452 } 453 } 454 455 private fun GetStateScope.calculatePermissionTreeFootprint(permissionTree: Permission): Int { 456 var size = 0 457 with(policy) { 458 getPermissions().forEachIndexed { _, _, permission -> 459 if (permissionTree.appId == permission.appId) { 460 size += permission.footprint 461 } 462 } 463 } 464 return size 465 } 466 467 override fun getPermissionRequestState( 468 packageName: String, 469 permissionName: String, 470 deviceId: Int, 471 persistentDeviceId: String 472 ): Int { 473 val pid = Binder.getCallingPid() 474 val uid = Binder.getCallingUid() 475 val deviceContext = if (deviceId == context.deviceId){ 476 context 477 } else { 478 context.createDeviceContext(deviceId) 479 } 480 val result = deviceContext.checkPermission(permissionName, pid, uid) 481 if (result == PackageManager.PERMISSION_GRANTED) { 482 return Context.PERMISSION_REQUEST_STATE_GRANTED 483 } 484 485 val appId = UserHandle.getAppId(uid) 486 val userId = UserHandle.getUserId(uid) 487 val packageState = 488 packageManagerLocal.withFilteredSnapshot(uid, userId).use { 489 it.getPackageState(packageName) 490 } ?: return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE 491 val androidPackage = 492 packageState.androidPackage ?: return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE 493 if (appId != packageState.appId) { 494 return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE 495 } 496 val permission = service.getState { with(policy) { getPermissions()[permissionName] } } 497 if (permission == null || !permission.isRuntime) { 498 return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE 499 } 500 if (permissionName !in androidPackage.requestedPermissions) { 501 return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE 502 } 503 504 val permissionFlags = 505 service.getState { 506 getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId) 507 } 508 val isUnreqestable = permissionFlags.hasAnyBit(UNREQUESTABLE_MASK) 509 // Special case for READ_MEDIA_IMAGES due to photo picker 510 if ((permissionName == Manifest.permission.READ_MEDIA_IMAGES || 511 permissionName == Manifest.permission.READ_MEDIA_VIDEO) && isUnreqestable) { 512 val isUserSelectedGranted = 513 deviceContext.checkPermission( 514 Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED, 515 pid, 516 uid, 517 ) == PackageManager.PERMISSION_GRANTED 518 val userSelectedPermissionFlags = 519 service.getState { 520 getPermissionFlagsWithPolicy( 521 appId, 522 userId, 523 Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED, 524 persistentDeviceId, 525 ) 526 } 527 if ( 528 isUserSelectedGranted && 529 userSelectedPermissionFlags.hasBits(PermissionFlags.USER_FIXED) 530 ) { 531 return Context.PERMISSION_REQUEST_STATE_REQUESTABLE 532 } 533 } 534 return if (isUnreqestable) { 535 Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE 536 } else { 537 Context.PERMISSION_REQUEST_STATE_REQUESTABLE 538 } 539 } 540 541 override fun checkUidPermission(uid: Int, permissionName: String, deviceId: String): Int { 542 val userId = UserHandle.getUserId(uid) 543 if (!userManagerInternal.exists(userId)) { 544 return PackageManager.PERMISSION_DENIED 545 } 546 547 // PackageManagerInternal.getPackage(int) already checks package visibility and enforces 548 // that instant apps can't see shared UIDs. Note that on the contrary, 549 // PackageManagerInternal.getPackage(String) doesn't perform any checks. 550 val androidPackage = packageManagerInternal.getPackage(uid) 551 if (androidPackage != null) { 552 // Note that PackageManagerInternal.getPackageStateInternal() is not filtered. 553 val packageState = 554 packageManagerInternal.getPackageStateInternal(androidPackage.packageName) 555 if (packageState == null) { 556 Slog.e( 557 LOG_TAG, 558 "checkUidPermission: PackageState not found for AndroidPackage" + 559 " $androidPackage" 560 ) 561 return PackageManager.PERMISSION_DENIED 562 } 563 564 val isPermissionGranted = 565 service.getState { 566 isPermissionGranted(packageState, userId, permissionName, deviceId) 567 } 568 return if (isPermissionGranted) { 569 PackageManager.PERMISSION_GRANTED 570 } else { 571 PackageManager.PERMISSION_DENIED 572 } 573 } 574 575 return if (isSystemUidPermissionGranted(uid, permissionName)) { 576 PackageManager.PERMISSION_GRANTED 577 } else { 578 PackageManager.PERMISSION_DENIED 579 } 580 } 581 582 /** Internal implementation that should only be called by [checkUidPermission]. */ 583 private fun isSystemUidPermissionGranted(uid: Int, permissionName: String): Boolean { 584 val uidPermissions = systemConfig.systemPermissions[uid] ?: return false 585 if (permissionName in uidPermissions) { 586 return true 587 } 588 589 val fullerPermissionName = FULLER_PERMISSIONS[permissionName] 590 if (fullerPermissionName != null && fullerPermissionName in uidPermissions) { 591 return true 592 } 593 594 return false 595 } 596 597 override fun checkPermission( 598 packageName: String, 599 permissionName: String, 600 deviceId: String, 601 userId: Int 602 ): Int { 603 if (!userManagerInternal.exists(userId)) { 604 return PackageManager.PERMISSION_DENIED 605 } 606 607 val packageState = 608 packageManagerLocal.withFilteredSnapshot(Binder.getCallingUid(), userId).use { 609 it.getPackageState(packageName) 610 } ?: return PackageManager.PERMISSION_DENIED 611 612 val isPermissionGranted = 613 service.getState { isPermissionGranted(packageState, userId, permissionName, deviceId) } 614 return if (isPermissionGranted) { 615 PackageManager.PERMISSION_GRANTED 616 } else { 617 PackageManager.PERMISSION_DENIED 618 } 619 } 620 621 /** 622 * Check whether a permission is granted, without any validation on caller. 623 * 624 * This method should always be called for checking whether a permission is granted, instead of 625 * reading permission flags directly from the policy. 626 */ 627 private fun GetStateScope.isPermissionGranted( 628 packageState: PackageState, 629 userId: Int, 630 permissionName: String, 631 deviceId: String 632 ): Boolean { 633 val appId = packageState.appId 634 // Note that instant apps can't have shared UIDs, so we only need to check the current 635 // package state. 636 val isInstantApp = packageState.getUserStateOrDefault(userId).isInstantApp 637 if (isSinglePermissionGranted(appId, userId, isInstantApp, permissionName, deviceId)) { 638 return true 639 } 640 641 val fullerPermissionName = FULLER_PERMISSIONS[permissionName] 642 if ( 643 fullerPermissionName != null && 644 isSinglePermissionGranted( 645 appId, 646 userId, 647 isInstantApp, 648 fullerPermissionName, 649 deviceId 650 ) 651 ) { 652 return true 653 } 654 655 return false 656 } 657 658 /** Internal implementation that should only be called by [isPermissionGranted]. */ 659 private fun GetStateScope.isSinglePermissionGranted( 660 appId: Int, 661 userId: Int, 662 isInstantApp: Boolean, 663 permissionName: String, 664 deviceId: String, 665 ): Boolean { 666 val flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) 667 if (!PermissionFlags.isPermissionGranted(flags)) { 668 return false 669 } 670 671 if (isInstantApp) { 672 val permission = with(policy) { getPermissions()[permissionName] } ?: return false 673 if (!permission.isInstant) { 674 return false 675 } 676 } 677 678 return true 679 } 680 681 override fun getGrantedPermissions(packageName: String, userId: Int): Set<String> { 682 requireNotNull(packageName) { "packageName cannot be null" } 683 Preconditions.checkArgumentNonnegative(userId, "userId") 684 685 val packageState = 686 packageManagerLocal.withUnfilteredSnapshot().use { it.getPackageState(packageName) } 687 if (packageState == null) { 688 Slog.w(LOG_TAG, "getGrantedPermissions: Unknown package $packageName") 689 return emptySet() 690 } 691 692 service.getState { 693 val permissionFlags = 694 with(policy) { getUidPermissionFlags(packageState.appId, userId) } 695 ?: return emptySet() 696 697 return permissionFlags.mapNotNullIndexedTo(ArraySet()) { _, permissionName, _ -> 698 if ( 699 isPermissionGranted( 700 packageState, 701 userId, 702 permissionName, 703 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT 704 ) 705 ) { 706 permissionName 707 } else { 708 null 709 } 710 } 711 } 712 } 713 714 override fun getGidsForUid(uid: Int): IntArray { 715 val appId = UserHandle.getAppId(uid) 716 val userId = UserHandle.getUserId(uid) 717 val globalGids = systemConfig.globalGids 718 service.getState { 719 // Different from the old implementation, which returns an empty array when the 720 // permission state is not found, now we always return at least global GIDs. This is 721 // more consistent with the pre-S-refactor behavior. This is also because we are now 722 // actively trimming the per-UID objects when empty. 723 val permissionFlags = 724 with(policy) { getUidPermissionFlags(appId, userId) } ?: return globalGids.copyOf() 725 726 val gids = GrowingIntArray.wrap(globalGids) 727 permissionFlags.forEachIndexed { _, permissionName, flags -> 728 if (!PermissionFlags.isPermissionGranted(flags)) { 729 return@forEachIndexed 730 } 731 732 val permission = 733 with(policy) { getPermissions()[permissionName] } ?: return@forEachIndexed 734 val permissionGids = permission.getGidsForUser(userId) 735 if (permissionGids.isEmpty()) { 736 return@forEachIndexed 737 } 738 gids.addAll(permissionGids) 739 } 740 return gids.toArray() 741 } 742 } 743 744 override fun grantRuntimePermission( 745 packageName: String, 746 permissionName: String, 747 deviceId: String, 748 userId: Int 749 ) { 750 setRuntimePermissionGranted(packageName, userId, permissionName, deviceId, isGranted = true) 751 } 752 753 override fun revokeRuntimePermission( 754 packageName: String, 755 permissionName: String, 756 deviceId: String, 757 userId: Int, 758 reason: String? 759 ) { 760 setRuntimePermissionGranted( 761 packageName, 762 userId, 763 permissionName, 764 deviceId, 765 isGranted = false, 766 revokeReason = reason 767 ) 768 } 769 770 override fun revokePostNotificationPermissionWithoutKillForTest( 771 packageName: String, 772 userId: Int 773 ) { 774 setRuntimePermissionGranted( 775 packageName, 776 userId, 777 Manifest.permission.POST_NOTIFICATIONS, 778 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, 779 isGranted = false, 780 skipKillUid = true 781 ) 782 } 783 784 /** 785 * Shared internal implementation that should only be called by [grantRuntimePermission], 786 * [revokeRuntimePermission] and [revokePostNotificationPermissionWithoutKillForTest]. 787 */ 788 private fun setRuntimePermissionGranted( 789 packageName: String, 790 userId: Int, 791 permissionName: String, 792 deviceId: String, 793 isGranted: Boolean, 794 skipKillUid: Boolean = false, 795 revokeReason: String? = null 796 ) { 797 val methodName = if (isGranted) "grantRuntimePermission" else "revokeRuntimePermission" 798 val callingUid = Binder.getCallingUid() 799 val isDebugEnabled = 800 if (isGranted) { 801 PermissionManager.DEBUG_TRACE_GRANTS 802 } else { 803 PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES 804 } 805 if ( 806 isDebugEnabled && 807 PermissionManager.shouldTraceGrant(packageName, permissionName, userId) 808 ) { 809 val callingUidName = packageManagerInternal.getNameForUid(callingUid) 810 Slog.i( 811 LOG_TAG, 812 "$methodName(packageName = $packageName," + 813 " permissionName = $permissionName" + 814 (if (isGranted) "" else "skipKillUid = $skipKillUid, reason = $revokeReason") + 815 ", userId = $userId," + 816 " callingUid = $callingUidName ($callingUid))," + 817 " deviceId = $deviceId", 818 RuntimeException() 819 ) 820 } 821 822 if (!userManagerInternal.exists(userId)) { 823 Slog.w(LOG_TAG, "$methodName: Unknown user $userId") 824 return 825 } 826 827 enforceCallingOrSelfCrossUserPermission( 828 userId, 829 enforceFullPermission = true, 830 enforceShellRestriction = true, 831 methodName 832 ) 833 val enforcedPermissionName = 834 if (isGranted) { 835 Manifest.permission.GRANT_RUNTIME_PERMISSIONS 836 } else { 837 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS 838 } 839 context.enforceCallingOrSelfPermission(enforcedPermissionName, methodName) 840 841 val packageState: PackageState? 842 val permissionControllerPackageName = 843 packageManagerInternal 844 .getKnownPackageNames( 845 KnownPackages.PACKAGE_PERMISSION_CONTROLLER, 846 UserHandle.USER_SYSTEM 847 ) 848 .first() 849 val permissionControllerPackageState: PackageState? 850 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 851 packageState = 852 snapshot.filtered(callingUid, userId).use { it.getPackageState(packageName) } 853 permissionControllerPackageState = 854 snapshot.getPackageState(permissionControllerPackageName) 855 } 856 val androidPackage = packageState?.androidPackage 857 // Different from the old implementation, which returns when package doesn't exist but 858 // throws when package exists but isn't visible, we now return in both cases to avoid 859 // leaking the package existence. 860 if (androidPackage == null) { 861 Slog.w(LOG_TAG, "$methodName: Unknown package $packageName") 862 return 863 } 864 865 val canManageRolePermission = 866 isRootOrSystemUid(callingUid) || 867 UserHandle.getAppId(callingUid) == permissionControllerPackageState!!.appId 868 val overridePolicyFixed = 869 context.checkCallingOrSelfPermission( 870 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY 871 ) == PackageManager.PERMISSION_GRANTED 872 873 service.mutateState { 874 with(onPermissionFlagsChangedListener) { 875 if (skipKillUid) { 876 skipKillRuntimePermissionRevokedUids() 877 } 878 if (revokeReason != null) { 879 addKillRuntimePermissionRevokedUidsReason(revokeReason) 880 } 881 } 882 883 setRuntimePermissionGranted( 884 packageState, 885 userId, 886 permissionName, 887 deviceId, 888 isGranted, 889 canManageRolePermission, 890 overridePolicyFixed, 891 reportError = true, 892 methodName 893 ) 894 } 895 } 896 897 private fun setRequestedPermissionStates( 898 packageState: PackageState, 899 userId: Int, 900 permissionStates: ArrayMap<String, Int> 901 ) { 902 service.mutateState { 903 permissionStates.forEachIndexed { _, permissionName, permissionState -> 904 when (permissionState) { 905 PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED, 906 PackageInstaller.SessionParams.PERMISSION_STATE_DENIED -> {} 907 else -> { 908 Slog.w( 909 LOG_TAG, 910 "setRequestedPermissionStates: Unknown permission state" + 911 " $permissionState for permission $permissionName" 912 ) 913 return@forEachIndexed 914 } 915 } 916 if (permissionName !in packageState.androidPackage!!.requestedPermissions) { 917 return@forEachIndexed 918 } 919 val permission = 920 with(policy) { getPermissions()[permissionName] } ?: return@forEachIndexed 921 when { 922 permission.isDevelopment || permission.isRuntime -> { 923 if ( 924 permissionState == 925 PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED 926 ) { 927 setRuntimePermissionGranted( 928 packageState, 929 userId, 930 permissionName, 931 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, 932 isGranted = true, 933 canManageRolePermission = false, 934 overridePolicyFixed = false, 935 reportError = false, 936 "setRequestedPermissionStates" 937 ) 938 updatePermissionFlags( 939 packageState.appId, 940 userId, 941 permissionName, 942 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, 943 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED or 944 PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, 945 0, 946 canUpdateSystemFlags = false, 947 reportErrorForUnknownPermission = false, 948 isPermissionRequested = true, 949 "setRequestedPermissionStates", 950 packageState.packageName 951 ) 952 } 953 } 954 permission.isAppOp && 955 permissionName in 956 PackageInstallerService.INSTALLER_CHANGEABLE_APP_OP_PERMISSIONS -> 957 setAppOpPermissionGranted( 958 packageState, 959 userId, 960 permissionName, 961 permissionState == 962 PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED 963 ) 964 else -> {} 965 } 966 } 967 } 968 } 969 970 /** Set whether a runtime permission is granted, without any validation on caller. */ 971 private fun MutateStateScope.setRuntimePermissionGranted( 972 packageState: PackageState, 973 userId: Int, 974 permissionName: String, 975 deviceId: String, 976 isGranted: Boolean, 977 canManageRolePermission: Boolean, 978 overridePolicyFixed: Boolean, 979 reportError: Boolean, 980 methodName: String 981 ) { 982 val permission = with(policy) { getPermissions()[permissionName] } 983 if (permission == null) { 984 if (reportError) { 985 throw IllegalArgumentException("Unknown permission $permissionName") 986 } 987 return 988 } 989 990 val androidPackage = packageState.androidPackage!! 991 val packageName = packageState.packageName 992 when { 993 permission.isDevelopment -> {} 994 permission.isRole -> { 995 if (!canManageRolePermission) { 996 if (reportError) { 997 throw SecurityException("Permission $permissionName is managed by role") 998 } 999 return 1000 } 1001 } 1002 permission.isRuntime -> { 1003 if (androidPackage.targetSdkVersion < Build.VERSION_CODES.M) { 1004 // If a permission review is required for legacy apps we represent 1005 // their permissions as always granted 1006 return 1007 } 1008 if ( 1009 isGranted && 1010 packageState.getUserStateOrDefault(userId).isInstantApp && 1011 !permission.isInstant 1012 ) { 1013 if (reportError) { 1014 throw SecurityException( 1015 "Cannot grant non-instant permission $permissionName to package" + 1016 " $packageName" 1017 ) 1018 } 1019 return 1020 } 1021 } 1022 else -> { 1023 if (reportError) { 1024 throw SecurityException( 1025 "Permission $permissionName requested by package $packageName is not a" + 1026 " changeable permission type" 1027 ) 1028 } 1029 return 1030 } 1031 } 1032 1033 val appId = packageState.appId 1034 val oldFlags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) 1035 1036 if (permissionName !in androidPackage.requestedPermissions && oldFlags == 0) { 1037 if (reportError) { 1038 Slog.e( 1039 LOG_TAG, 1040 "Permission $permissionName isn't requested by package $packageName" 1041 ) 1042 } 1043 return 1044 } 1045 1046 if (oldFlags.hasBits(PermissionFlags.SYSTEM_FIXED)) { 1047 if (reportError) { 1048 Slog.e( 1049 LOG_TAG, 1050 "$methodName: Cannot change system fixed permission $permissionName" + 1051 " for package $packageName" 1052 ) 1053 } 1054 return 1055 } 1056 1057 if (oldFlags.hasBits(PermissionFlags.POLICY_FIXED) && !overridePolicyFixed) { 1058 if (reportError) { 1059 Slog.e( 1060 LOG_TAG, 1061 "$methodName: Cannot change policy fixed permission $permissionName" + 1062 " for package $packageName" 1063 ) 1064 } 1065 return 1066 } 1067 1068 if (isGranted && oldFlags.hasBits(PermissionFlags.RESTRICTION_REVOKED)) { 1069 if (reportError) { 1070 Slog.e( 1071 LOG_TAG, 1072 "$methodName: Cannot grant hard-restricted non-exempt permission" + 1073 " $permissionName to package $packageName" 1074 ) 1075 } 1076 return 1077 } 1078 1079 if (isGranted && oldFlags.hasBits(PermissionFlags.SOFT_RESTRICTED)) { 1080 if (reportError) { 1081 Slog.e( 1082 LOG_TAG, 1083 "$methodName: Cannot grant soft-restricted non-exempt permission" + 1084 " $permissionName to package $packageName" 1085 ) 1086 } 1087 return 1088 } 1089 1090 val newFlags = PermissionFlags.updateRuntimePermissionGranted(oldFlags, isGranted) 1091 if (oldFlags == newFlags) { 1092 return 1093 } 1094 1095 setPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId, newFlags) 1096 1097 if (permission.isRuntime) { 1098 val action = 1099 if (isGranted) { 1100 MetricsProto.MetricsEvent.ACTION_PERMISSION_GRANTED 1101 } else { 1102 MetricsProto.MetricsEvent.ACTION_PERMISSION_REVOKED 1103 } 1104 val log = 1105 LogMaker(action).apply { 1106 setPackageName(packageName) 1107 addTaggedData(MetricsProto.MetricsEvent.FIELD_PERMISSION, permissionName) 1108 } 1109 metricsLogger.write(log) 1110 } 1111 } 1112 1113 private fun MutateStateScope.setAppOpPermissionGranted( 1114 packageState: PackageState, 1115 userId: Int, 1116 permissionName: String, 1117 isGranted: Boolean 1118 ) { 1119 val appOpPolicy = 1120 service.getSchemePolicy(UidUri.SCHEME, AppOpUri.SCHEME) as AppIdAppOpPolicy 1121 val appOpName = AppOpsManager.permissionToOp(permissionName)!! 1122 val mode = if (isGranted) AppOpsManager.MODE_ALLOWED else AppOpsManager.MODE_ERRORED 1123 with(appOpPolicy) { setAppOpMode(packageState.appId, userId, appOpName, mode) } 1124 } 1125 1126 override fun getPermissionFlags( 1127 packageName: String, 1128 permissionName: String, 1129 deviceId: String, 1130 userId: Int, 1131 ): Int { 1132 if (!userManagerInternal.exists(userId)) { 1133 Slog.w(LOG_TAG, "getPermissionFlags: Unknown user $userId") 1134 return 0 1135 } 1136 1137 enforceCallingOrSelfCrossUserPermission( 1138 userId, 1139 enforceFullPermission = true, 1140 enforceShellRestriction = false, 1141 "getPermissionFlags" 1142 ) 1143 enforceCallingOrSelfAnyPermission( 1144 "getPermissionFlags", 1145 Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 1146 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 1147 Manifest.permission.GET_RUNTIME_PERMISSIONS 1148 ) 1149 1150 val packageState = 1151 packageManagerLocal.withFilteredSnapshot().use { it.getPackageState(packageName) } 1152 if (packageState == null) { 1153 Slog.w(LOG_TAG, "getPermissionFlags: Unknown package $packageName") 1154 return 0 1155 } 1156 1157 service.getState { 1158 val permission = with(policy) { getPermissions()[permissionName] } 1159 if (permission == null) { 1160 Slog.w(LOG_TAG, "getPermissionFlags: Unknown permission $permissionName") 1161 return 0 1162 } 1163 1164 val flags = 1165 getPermissionFlagsWithPolicy(packageState.appId, userId, permissionName, deviceId) 1166 1167 return PermissionFlags.toApiFlags(flags) 1168 } 1169 } 1170 1171 override fun getAllPermissionStates( 1172 packageName: String, 1173 deviceId: String, 1174 userId: Int 1175 ): Map<String, PermissionState> { 1176 if (!userManagerInternal.exists(userId)) { 1177 Slog.w(LOG_TAG, "getAllPermissionStates: Unknown user $userId") 1178 return emptyMap() 1179 } 1180 enforceCallingOrSelfCrossUserPermission( 1181 userId, 1182 enforceFullPermission = true, 1183 enforceShellRestriction = false, 1184 "getAllPermissionStates" 1185 ) 1186 enforceCallingOrSelfAnyPermission( 1187 "getAllPermissionStates", 1188 Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 1189 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 1190 Manifest.permission.GET_RUNTIME_PERMISSIONS 1191 ) 1192 1193 val packageState = 1194 packageManagerLocal.withFilteredSnapshot().use { it.getPackageState(packageName) } 1195 if (packageState == null) { 1196 Slog.w(LOG_TAG, "getAllPermissionStates: Unknown package $packageName") 1197 return emptyMap() 1198 } 1199 1200 service.getState { 1201 val permissionFlags = 1202 if (deviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT) { 1203 with(policy) { getAllPermissionFlags(packageState.appId, userId) } 1204 } else { 1205 with(devicePolicy) { 1206 getAllPermissionFlags(packageState.appId, deviceId, userId) 1207 } 1208 } ?: return emptyMap() 1209 val permissionStates = ArrayMap<String, PermissionState>() 1210 permissionFlags.forEachIndexed { _, permissionName, flags -> 1211 val granted = isPermissionGranted(packageState, userId, permissionName, deviceId) 1212 val apiFlags = PermissionFlags.toApiFlags(flags) 1213 permissionStates[permissionName] = PermissionState(granted, apiFlags) 1214 } 1215 return permissionStates 1216 } 1217 } 1218 1219 override fun isPermissionRevokedByPolicy( 1220 packageName: String, 1221 permissionName: String, 1222 deviceId: String, 1223 userId: Int 1224 ): Boolean { 1225 if (!userManagerInternal.exists(userId)) { 1226 Slog.w(LOG_TAG, "isPermissionRevokedByPolicy: Unknown user $userId") 1227 return false 1228 } 1229 1230 enforceCallingOrSelfCrossUserPermission( 1231 userId, 1232 enforceFullPermission = true, 1233 enforceShellRestriction = false, 1234 "isPermissionRevokedByPolicy" 1235 ) 1236 1237 val packageState = 1238 packageManagerLocal.withFilteredSnapshot(Binder.getCallingUid(), userId).use { 1239 it.getPackageState(packageName) 1240 } ?: return false 1241 1242 service.getState { 1243 if (isPermissionGranted(packageState, userId, permissionName, deviceId)) { 1244 return false 1245 } 1246 1247 val flags = 1248 getPermissionFlagsWithPolicy(packageState.appId, userId, permissionName, deviceId) 1249 1250 return flags.hasBits(PermissionFlags.POLICY_FIXED) 1251 } 1252 } 1253 1254 override fun isPermissionsReviewRequired(packageName: String, userId: Int): Boolean { 1255 requireNotNull(packageName) { "packageName cannot be null" } 1256 // TODO(b/173235285): Some caller may pass USER_ALL as userId. 1257 // Preconditions.checkArgumentNonnegative(userId, "userId") 1258 1259 val packageState = 1260 packageManagerLocal.withUnfilteredSnapshot().use { it.getPackageState(packageName) } 1261 ?: return false 1262 1263 val permissionFlags = 1264 service.getState { with(policy) { getUidPermissionFlags(packageState.appId, userId) } } 1265 ?: return false 1266 return permissionFlags.anyIndexed { _, _, it -> it.hasBits(REVIEW_REQUIRED_FLAGS) } 1267 } 1268 1269 override fun shouldShowRequestPermissionRationale( 1270 packageName: String, 1271 permissionName: String, 1272 deviceId: String, 1273 userId: Int, 1274 ): Boolean { 1275 if (!userManagerInternal.exists(userId)) { 1276 Slog.w(LOG_TAG, "shouldShowRequestPermissionRationale: Unknown user $userId") 1277 return false 1278 } 1279 1280 enforceCallingOrSelfCrossUserPermission( 1281 userId, 1282 enforceFullPermission = true, 1283 enforceShellRestriction = false, 1284 "shouldShowRequestPermissionRationale" 1285 ) 1286 1287 val callingUid = Binder.getCallingUid() 1288 val packageState = 1289 packageManagerLocal.withFilteredSnapshot(callingUid, userId).use { 1290 it.getPackageState(packageName) 1291 } ?: return false 1292 val appId = packageState.appId 1293 if (UserHandle.getAppId(callingUid) != appId) { 1294 return false 1295 } 1296 1297 val flags: Int 1298 service.getState { 1299 if (isPermissionGranted(packageState, userId, permissionName, deviceId)) { 1300 return false 1301 } 1302 1303 flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) 1304 } 1305 if (flags.hasAnyBit(UNREQUESTABLE_MASK)) { 1306 return false 1307 } 1308 1309 if (permissionName == Manifest.permission.ACCESS_BACKGROUND_LOCATION) { 1310 val isBackgroundRationaleChangeEnabled = 1311 Binder::class.withClearedCallingIdentity { 1312 try { 1313 platformCompat.isChangeEnabledByPackageName( 1314 BACKGROUND_RATIONALE_CHANGE_ID, 1315 packageName, 1316 userId 1317 ) 1318 } catch (e: RemoteException) { 1319 Slog.e( 1320 LOG_TAG, 1321 "shouldShowRequestPermissionRationale: Unable to check if" + 1322 " compatibility change is enabled", 1323 e 1324 ) 1325 false 1326 } 1327 } 1328 if (isBackgroundRationaleChangeEnabled) { 1329 return true 1330 } 1331 } 1332 1333 return flags.hasBits(PermissionFlags.USER_SET) 1334 } 1335 1336 override fun updatePermissionFlags( 1337 packageName: String, 1338 permissionName: String, 1339 flagMask: Int, 1340 flagValues: Int, 1341 enforceAdjustPolicyPermission: Boolean, 1342 deviceId: String, 1343 userId: Int 1344 ) { 1345 val callingUid = Binder.getCallingUid() 1346 if ( 1347 PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES && 1348 PermissionManager.shouldTraceGrant(packageName, permissionName, userId) 1349 ) { 1350 val flagMaskString = 1351 DebugUtils.flagsToString( 1352 PackageManager::class.java, 1353 "FLAG_PERMISSION_", 1354 flagMask.toLong() 1355 ) 1356 val flagValuesString = 1357 DebugUtils.flagsToString( 1358 PackageManager::class.java, 1359 "FLAG_PERMISSION_", 1360 flagValues.toLong() 1361 ) 1362 val callingUidName = packageManagerInternal.getNameForUid(callingUid) 1363 Slog.i( 1364 LOG_TAG, 1365 "updatePermissionFlags(packageName = $packageName," + 1366 " permissionName = $permissionName, flagMask = $flagMaskString," + 1367 " flagValues = $flagValuesString, userId = $userId," + 1368 " deviceId = $deviceId," + 1369 " callingUid = $callingUidName ($callingUid))", 1370 RuntimeException() 1371 ) 1372 } 1373 1374 if (!userManagerInternal.exists(userId)) { 1375 Slog.w(LOG_TAG, "updatePermissionFlags: Unknown user $userId") 1376 return 1377 } 1378 1379 enforceCallingOrSelfCrossUserPermission( 1380 userId, 1381 enforceFullPermission = true, 1382 enforceShellRestriction = true, 1383 "updatePermissionFlags" 1384 ) 1385 enforceCallingOrSelfAnyPermission( 1386 "updatePermissionFlags", 1387 Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 1388 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS 1389 ) 1390 1391 // Different from the old implementation, which implicitly didn't allow modifying the 1392 // POLICY_FIXED flag if the caller is system or root UID, now we do allow that since system 1393 // and root UIDs are supposed to have all permissions including 1394 // ADJUST_RUNTIME_PERMISSIONS_POLICY. 1395 if (!isRootOrSystemUid(callingUid)) { 1396 if (flagMask.hasBits(PackageManager.FLAG_PERMISSION_POLICY_FIXED)) { 1397 if (enforceAdjustPolicyPermission) { 1398 context.enforceCallingOrSelfPermission( 1399 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, 1400 "Need ${Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY} to change" + 1401 " policy flags" 1402 ) 1403 } else { 1404 val targetSdkVersion = packageManagerInternal.getUidTargetSdkVersion(callingUid) 1405 require(targetSdkVersion < Build.VERSION_CODES.Q) { 1406 "${Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY} needs to be" + 1407 " checked for packages targeting ${Build.VERSION_CODES.Q} or later" + 1408 " when changing policy flags" 1409 } 1410 } 1411 } 1412 } 1413 1414 // Using PackageManagerInternal instead of PackageManagerLocal for now due to need to access 1415 // shared user packages. 1416 // TODO: We probably shouldn't check the share user packages, since the package name is 1417 // explicitly provided and grantRuntimePermission() isn't checking shared user packages 1418 // anyway. 1419 val packageState = packageManagerInternal.getPackageStateInternal(packageName) 1420 val androidPackage = packageState?.androidPackage 1421 // Different from the old implementation, which returns when package doesn't exist but 1422 // throws when package exists but isn't visible, we now return in both cases to avoid 1423 // leaking the package existence. 1424 if ( 1425 androidPackage == null || 1426 packageManagerInternal.filterAppAccess(packageName, callingUid, userId, false) 1427 ) { 1428 Slog.w(LOG_TAG, "updatePermissionFlags: Unknown package $packageName") 1429 return 1430 } 1431 1432 // Different from the old implementation, which only allowed the system UID to modify the 1433 // following flags, we now allow the root UID as well since both should have all 1434 // permissions. 1435 val canUpdateSystemFlags = isRootOrSystemUid(callingUid) 1436 1437 val isPermissionRequested = 1438 if (permissionName in androidPackage.requestedPermissions) { 1439 // Fast path, the current package has requested the permission. 1440 true 1441 } else { 1442 // Slow path, go through all shared user packages. 1443 val sharedUserPackageNames = 1444 packageManagerInternal.getSharedUserPackagesForPackage(packageName, userId) 1445 sharedUserPackageNames.any { sharedUserPackageName -> 1446 val sharedUserPackage = packageManagerInternal.getPackage(sharedUserPackageName) 1447 sharedUserPackage != null && 1448 permissionName in sharedUserPackage.requestedPermissions 1449 } 1450 } 1451 1452 val appId = packageState.appId 1453 service.mutateState { 1454 updatePermissionFlags( 1455 appId, 1456 userId, 1457 permissionName, 1458 deviceId, 1459 flagMask, 1460 flagValues, 1461 canUpdateSystemFlags, 1462 reportErrorForUnknownPermission = true, 1463 isPermissionRequested, 1464 "updatePermissionFlags", 1465 packageName 1466 ) 1467 } 1468 } 1469 1470 override fun updatePermissionFlagsForAllApps(flagMask: Int, flagValues: Int, userId: Int) { 1471 val callingUid = Binder.getCallingUid() 1472 if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES) { 1473 val flagMaskString = 1474 DebugUtils.flagsToString( 1475 PackageManager::class.java, 1476 "FLAG_PERMISSION_", 1477 flagMask.toLong() 1478 ) 1479 val flagValuesString = 1480 DebugUtils.flagsToString( 1481 PackageManager::class.java, 1482 "FLAG_PERMISSION_", 1483 flagValues.toLong() 1484 ) 1485 val callingUidName = packageManagerInternal.getNameForUid(callingUid) 1486 Slog.i( 1487 LOG_TAG, 1488 "updatePermissionFlagsForAllApps(flagMask = $flagMaskString," + 1489 " flagValues = $flagValuesString, userId = $userId," + 1490 " callingUid = $callingUidName ($callingUid))", 1491 RuntimeException() 1492 ) 1493 } 1494 1495 if (!userManagerInternal.exists(userId)) { 1496 Slog.w(LOG_TAG, "updatePermissionFlagsForAllApps: Unknown user $userId") 1497 return 1498 } 1499 1500 enforceCallingOrSelfCrossUserPermission( 1501 userId, 1502 enforceFullPermission = true, 1503 enforceShellRestriction = true, 1504 "updatePermissionFlagsForAllApps" 1505 ) 1506 enforceCallingOrSelfAnyPermission( 1507 "updatePermissionFlagsForAllApps", 1508 Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 1509 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS 1510 ) 1511 1512 // Different from the old implementation, which only sanitized the SYSTEM_FIXED 1513 // flag, we now properly sanitize all flags as in updatePermissionFlags(). 1514 val canUpdateSystemFlags = isRootOrSystemUid(callingUid) 1515 1516 val packageStates = packageManagerLocal.withUnfilteredSnapshot().use { it.packageStates } 1517 service.mutateState { 1518 packageStates.forEach { (packageName, packageState) -> 1519 if (packageState.isApex) { 1520 return@forEach 1521 } 1522 val androidPackage = packageState.androidPackage ?: return@forEach 1523 androidPackage.requestedPermissions.forEach { permissionName -> 1524 updatePermissionFlags( 1525 packageState.appId, 1526 userId, 1527 permissionName, 1528 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, 1529 flagMask, 1530 flagValues, 1531 canUpdateSystemFlags, 1532 reportErrorForUnknownPermission = false, 1533 isPermissionRequested = true, 1534 "updatePermissionFlagsForAllApps", 1535 packageName 1536 ) 1537 } 1538 } 1539 } 1540 } 1541 1542 /** Update flags for a permission, without any validation on caller. */ 1543 private fun MutateStateScope.updatePermissionFlags( 1544 appId: Int, 1545 userId: Int, 1546 permissionName: String, 1547 deviceId: String, 1548 flagMask: Int, 1549 flagValues: Int, 1550 canUpdateSystemFlags: Boolean, 1551 reportErrorForUnknownPermission: Boolean, 1552 isPermissionRequested: Boolean, 1553 methodName: String, 1554 packageName: String 1555 ) { 1556 @Suppress("NAME_SHADOWING") var flagMask = flagMask 1557 @Suppress("NAME_SHADOWING") var flagValues = flagValues 1558 // Only the system can change these flags and nothing else. 1559 if (!canUpdateSystemFlags) { 1560 // Different from the old implementation, which allowed non-system UIDs to remove (but 1561 // not add) permission restriction flags, we now consistently ignore them altogether. 1562 val ignoredMask = 1563 PackageManager.FLAG_PERMISSION_SYSTEM_FIXED or 1564 PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT or 1565 PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT or 1566 PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT or 1567 PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT or 1568 PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION 1569 flagMask = flagMask andInv ignoredMask 1570 flagValues = flagValues andInv ignoredMask 1571 } 1572 1573 val permission = with(policy) { getPermissions()[permissionName] } 1574 if (permission == null) { 1575 if (reportErrorForUnknownPermission) { 1576 throw IllegalArgumentException("Unknown permission $permissionName") 1577 } 1578 return 1579 } 1580 1581 val oldFlags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) 1582 if (!isPermissionRequested && oldFlags == 0) { 1583 Slog.w( 1584 LOG_TAG, 1585 "$methodName: Permission $permissionName isn't requested by package" + 1586 " $packageName" 1587 ) 1588 return 1589 } 1590 1591 val newFlags = PermissionFlags.updateFlags(permission, oldFlags, flagMask, flagValues) 1592 setPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId, newFlags) 1593 } 1594 1595 override fun getAllowlistedRestrictedPermissions( 1596 packageName: String, 1597 allowlistedFlags: Int, 1598 userId: Int 1599 ): ArrayList<String>? { 1600 requireNotNull(packageName) { "packageName cannot be null" } 1601 Preconditions.checkFlagsArgument(allowlistedFlags, PERMISSION_ALLOWLIST_MASK) 1602 Preconditions.checkArgumentNonnegative(userId, "userId cannot be null") 1603 1604 if (!userManagerInternal.exists(userId)) { 1605 Slog.w(LOG_TAG, "AllowlistedRestrictedPermission api: Unknown user $userId") 1606 return null 1607 } 1608 1609 enforceCallingOrSelfCrossUserPermission( 1610 userId, 1611 enforceFullPermission = false, 1612 enforceShellRestriction = false, 1613 "getAllowlistedRestrictedPermissions" 1614 ) 1615 1616 val callingUid = Binder.getCallingUid() 1617 val packageState = 1618 packageManagerLocal.withFilteredSnapshot(callingUid, userId).use { 1619 it.getPackageState(packageName) 1620 } ?: return null 1621 val androidPackage = packageState.androidPackage ?: return null 1622 1623 val isCallerPrivileged = 1624 context.checkCallingOrSelfPermission( 1625 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS 1626 ) == PackageManager.PERMISSION_GRANTED 1627 1628 if ( 1629 allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) && 1630 !isCallerPrivileged 1631 ) { 1632 throw SecurityException( 1633 "Querying system allowlist requires " + 1634 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS 1635 ) 1636 } 1637 1638 val isCallerInstallerOnRecord = 1639 packageManagerInternal.isCallerInstallerOfRecord(androidPackage, callingUid) 1640 1641 if ( 1642 allowlistedFlags.hasAnyBit( 1643 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE or 1644 PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER 1645 ) 1646 ) { 1647 if (!isCallerPrivileged && !isCallerInstallerOnRecord) { 1648 throw SecurityException( 1649 "Querying upgrade or installer allowlist requires being installer on record" + 1650 " or ${Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS}" 1651 ) 1652 } 1653 } 1654 1655 return getAllowlistedRestrictedPermissionsUnchecked( 1656 packageState.appId, 1657 allowlistedFlags, 1658 userId 1659 ) 1660 } 1661 1662 private fun GetStateScope.getPermissionFlagsWithPolicy( 1663 appId: Int, 1664 userId: Int, 1665 permissionName: String, 1666 deviceId: String, 1667 ): Int { 1668 return if ( 1669 !Flags.deviceAwarePermissionApisEnabled() || 1670 deviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT 1671 ) { 1672 with(policy) { getPermissionFlags(appId, userId, permissionName) } 1673 } else { 1674 if (permissionName !in PermissionManager.DEVICE_AWARE_PERMISSIONS) { 1675 Slog.i( 1676 LOG_TAG, 1677 "$permissionName is not device aware permission, " + 1678 " get the flags for default device." 1679 ) 1680 return with(policy) { getPermissionFlags(appId, userId, permissionName) } 1681 } 1682 with(devicePolicy) { getPermissionFlags(appId, deviceId, userId, permissionName) } 1683 } 1684 } 1685 1686 private fun MutateStateScope.setPermissionFlagsWithPolicy( 1687 appId: Int, 1688 userId: Int, 1689 permissionName: String, 1690 deviceId: String, 1691 flags: Int 1692 ): Boolean { 1693 return if ( 1694 !Flags.deviceAwarePermissionApisEnabled() || 1695 deviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT 1696 ) { 1697 with(policy) { setPermissionFlags(appId, userId, permissionName, flags) } 1698 } else { 1699 if (permissionName !in PermissionManager.DEVICE_AWARE_PERMISSIONS) { 1700 Slog.i( 1701 LOG_TAG, 1702 "$permissionName is not device aware permission, " + 1703 " set the flags for default device." 1704 ) 1705 return with(policy) { setPermissionFlags(appId, userId, permissionName, flags) } 1706 } 1707 1708 with(devicePolicy) { 1709 setPermissionFlags(appId, deviceId, userId, permissionName, flags) 1710 } 1711 } 1712 } 1713 1714 /** 1715 * This method does not enforce checks on the caller, should only be called after required 1716 * checks. 1717 */ 1718 private fun getAllowlistedRestrictedPermissionsUnchecked( 1719 appId: Int, 1720 allowlistedFlags: Int, 1721 userId: Int 1722 ): ArrayList<String>? { 1723 val permissionFlags = 1724 service.getState { with(policy) { getUidPermissionFlags(appId, userId) } } 1725 ?: return null 1726 1727 var queryFlags = 0 1728 if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM)) { 1729 queryFlags = queryFlags or PermissionFlags.SYSTEM_EXEMPT 1730 } 1731 if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE)) { 1732 queryFlags = queryFlags or PermissionFlags.UPGRADE_EXEMPT 1733 } 1734 if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) { 1735 queryFlags = queryFlags or PermissionFlags.INSTALLER_EXEMPT 1736 } 1737 1738 return permissionFlags.mapNotNullIndexedTo(ArrayList()) { _, permissionName, flags -> 1739 if (flags.hasAnyBit(queryFlags)) permissionName else null 1740 } 1741 } 1742 1743 override fun addAllowlistedRestrictedPermission( 1744 packageName: String, 1745 permissionName: String, 1746 allowlistedFlags: Int, 1747 userId: Int 1748 ): Boolean { 1749 requireNotNull(permissionName) { "permissionName cannot be null" } 1750 if (!enforceRestrictedPermission(permissionName)) { 1751 return false 1752 } 1753 1754 val permissionNames = 1755 getAllowlistedRestrictedPermissions(packageName, allowlistedFlags, userId) 1756 ?: ArrayList(1) 1757 1758 if (permissionName !in permissionNames) { 1759 permissionNames += permissionName 1760 return setAllowlistedRestrictedPermissions( 1761 packageName, 1762 permissionNames, 1763 allowlistedFlags, 1764 userId, 1765 isAddingPermission = true 1766 ) 1767 } 1768 return false 1769 } 1770 1771 private fun addAllowlistedRestrictedPermissionsUnchecked( 1772 androidPackage: AndroidPackage, 1773 appId: Int, 1774 permissionNames: List<String>, 1775 userId: Int 1776 ) { 1777 val newPermissionNames = 1778 getAllowlistedRestrictedPermissionsUnchecked( 1779 appId, 1780 PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER, 1781 userId 1782 ) 1783 ?.let { ArraySet(permissionNames).apply { this += it }.toList() } ?: permissionNames 1784 1785 setAllowlistedRestrictedPermissionsUnchecked( 1786 androidPackage, 1787 appId, 1788 newPermissionNames, 1789 PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER, 1790 userId 1791 ) 1792 } 1793 1794 override fun removeAllowlistedRestrictedPermission( 1795 packageName: String, 1796 permissionName: String, 1797 allowlistedFlags: Int, 1798 userId: Int 1799 ): Boolean { 1800 requireNotNull(permissionName) { "permissionName cannot be null" } 1801 if (!enforceRestrictedPermission(permissionName)) { 1802 return false 1803 } 1804 1805 val permissions = 1806 getAllowlistedRestrictedPermissions(packageName, allowlistedFlags, userId) 1807 ?: return false 1808 1809 if (permissions.remove(permissionName)) { 1810 return setAllowlistedRestrictedPermissions( 1811 packageName, 1812 permissions, 1813 allowlistedFlags, 1814 userId, 1815 isAddingPermission = false 1816 ) 1817 } 1818 1819 return false 1820 } 1821 1822 private fun enforceRestrictedPermission(permissionName: String): Boolean { 1823 val permission = service.getState { with(policy) { getPermissions()[permissionName] } } 1824 if (permission == null) { 1825 Slog.w(LOG_TAG, "permission definition for $permissionName does not exist") 1826 return false 1827 } 1828 1829 if ( 1830 packageManagerLocal.withFilteredSnapshot().use { 1831 it.getPackageState(permission.packageName) 1832 } == null 1833 ) { 1834 return false 1835 } 1836 1837 val isImmutablyRestrictedPermission = 1838 permission.isHardOrSoftRestricted && permission.isImmutablyRestricted 1839 if ( 1840 isImmutablyRestrictedPermission && 1841 context.checkCallingOrSelfPermission( 1842 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS 1843 ) != PackageManager.PERMISSION_GRANTED 1844 ) { 1845 throw SecurityException( 1846 "Cannot modify allowlist of an immutably restricted permission: ${permission.name}" 1847 ) 1848 } 1849 1850 return true 1851 } 1852 1853 private fun setAllowlistedRestrictedPermissions( 1854 packageName: String, 1855 permissionNames: List<String>, 1856 allowlistedFlags: Int, 1857 userId: Int, 1858 isAddingPermission: Boolean 1859 ): Boolean { 1860 Preconditions.checkArgument(allowlistedFlags.countOneBits() == 1) 1861 1862 val isCallerPrivileged = 1863 context.checkCallingOrSelfPermission( 1864 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS 1865 ) == PackageManager.PERMISSION_GRANTED 1866 1867 val callingUid = Binder.getCallingUid() 1868 val packageState = 1869 packageManagerLocal.withFilteredSnapshot(callingUid, userId).use { snapshot -> 1870 snapshot.packageStates[packageName] ?: return false 1871 } 1872 val androidPackage = packageState.androidPackage ?: return false 1873 1874 val isCallerInstallerOnRecord = 1875 packageManagerInternal.isCallerInstallerOfRecord(androidPackage, callingUid) 1876 1877 if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE)) { 1878 if (!isCallerPrivileged && !isCallerInstallerOnRecord) { 1879 throw SecurityException( 1880 "Modifying upgrade allowlist requires being installer on record or " + 1881 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS 1882 ) 1883 } 1884 if (isAddingPermission && !isCallerPrivileged) { 1885 throw SecurityException( 1886 "Adding to upgrade allowlist requires" + 1887 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS 1888 ) 1889 } 1890 } 1891 1892 setAllowlistedRestrictedPermissionsUnchecked( 1893 androidPackage, 1894 packageState.appId, 1895 permissionNames, 1896 allowlistedFlags, 1897 userId 1898 ) 1899 1900 return true 1901 } 1902 1903 /** 1904 * This method does not enforce checks on the caller, should only be called after required 1905 * checks. 1906 */ 1907 private fun setAllowlistedRestrictedPermissionsUnchecked( 1908 androidPackage: AndroidPackage, 1909 appId: Int, 1910 permissionNames: List<String>, 1911 allowlistedFlags: Int, 1912 userId: Int 1913 ) { 1914 var exemptMask = 0 1915 if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM)) { 1916 exemptMask = exemptMask or PermissionFlags.SYSTEM_EXEMPT 1917 } 1918 if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE)) { 1919 exemptMask = exemptMask or PermissionFlags.UPGRADE_EXEMPT 1920 } 1921 if (allowlistedFlags.hasBits(PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) { 1922 exemptMask = exemptMask or PermissionFlags.INSTALLER_EXEMPT 1923 } 1924 1925 service.mutateState { 1926 with(policy) { 1927 val permissions = getPermissions() 1928 androidPackage.requestedPermissions.forEachIndexed { _, requestedPermission -> 1929 val permission = permissions[requestedPermission] 1930 if (permission == null || !permission.isHardOrSoftRestricted) { 1931 return@forEachIndexed 1932 } 1933 1934 var exemptFlags = if (requestedPermission in permissionNames) exemptMask else 0 1935 updatePermissionExemptFlags(appId, userId, permission, exemptMask, exemptFlags) 1936 } 1937 } 1938 } 1939 } 1940 1941 override fun resetRuntimePermissions(androidPackage: AndroidPackage, userId: Int) { 1942 service.mutateState { 1943 with(policy) { resetRuntimePermissions(androidPackage.packageName, userId) } 1944 with(devicePolicy) { resetRuntimePermissions(androidPackage.packageName, userId) } 1945 } 1946 } 1947 1948 override fun resetRuntimePermissionsForUser(userId: Int) { 1949 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 1950 service.mutateState { 1951 snapshot.packageStates.forEach { (_, packageState) -> 1952 if (packageState.isApex) { 1953 return@forEach 1954 } 1955 with(policy) { resetRuntimePermissions(packageState.packageName, userId) } 1956 with(devicePolicy) { resetRuntimePermissions(packageState.packageName, userId) } 1957 } 1958 } 1959 } 1960 } 1961 1962 override fun addOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) { 1963 context.enforceCallingOrSelfPermission( 1964 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 1965 "addOnPermissionsChangeListener" 1966 ) 1967 1968 onPermissionsChangeListeners.addListener(listener) 1969 } 1970 1971 override fun removeOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) { 1972 context.enforceCallingOrSelfPermission( 1973 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 1974 "removeOnPermissionsChangeListener" 1975 ) 1976 1977 onPermissionsChangeListeners.removeListener(listener) 1978 } 1979 1980 override fun getSplitPermissions(): List<SplitPermissionInfoParcelable> { 1981 return PermissionManager.splitPermissionInfoListToParcelableList( 1982 systemConfig.splitPermissions 1983 ) 1984 } 1985 1986 override fun getAppOpPermissionPackages(permissionName: String): Array<String> { 1987 requireNotNull(permissionName) { "permissionName cannot be null" } 1988 val packageNames = ArraySet<String>() 1989 1990 val permission = service.getState { with(policy) { getPermissions()[permissionName] } } 1991 if (permission == null || !permission.isAppOp) { 1992 packageNames.toTypedArray() 1993 } 1994 1995 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 1996 snapshot.packageStates.forEach { (_, packageState) -> 1997 if (packageState.isApex) { 1998 return@forEach 1999 } 2000 val androidPackage = packageState.androidPackage ?: return@forEach 2001 if (permissionName in androidPackage.requestedPermissions) { 2002 packageNames += androidPackage.packageName 2003 } 2004 } 2005 } 2006 2007 return packageNames.toTypedArray() 2008 } 2009 2010 override fun getAllAppOpPermissionPackages(): Map<String, Set<String>> { 2011 val appOpPermissionPackageNames = ArrayMap<String, ArraySet<String>>() 2012 val permissions = service.getState { with(policy) { getPermissions() } } 2013 packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> 2014 snapshot.packageStates.forEach packageStates@{ (_, packageState) -> 2015 if (packageState.isApex) { 2016 return@packageStates 2017 } 2018 val androidPackage = packageState.androidPackage ?: return@packageStates 2019 androidPackage.requestedPermissions.forEach requestedPermissions@{ permissionName -> 2020 val permission = permissions[permissionName] ?: return@requestedPermissions 2021 if (permission.isAppOp) { 2022 val packageNames = 2023 appOpPermissionPackageNames.getOrPut(permissionName) { ArraySet() } 2024 packageNames += androidPackage.packageName 2025 } 2026 } 2027 } 2028 } 2029 return appOpPermissionPackageNames 2030 } 2031 2032 override fun backupRuntimePermissions(userId: Int): ByteArray? { 2033 Preconditions.checkArgumentNonnegative(userId, "userId cannot be null") 2034 val backup = CompletableFuture<ByteArray>() 2035 permissionControllerManager.getRuntimePermissionBackup( 2036 UserHandle.of(userId), 2037 PermissionThread.getExecutor(), 2038 backup::complete 2039 ) 2040 2041 return try { 2042 backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) 2043 } catch (e: Exception) { 2044 when (e) { 2045 is TimeoutException, 2046 is InterruptedException, 2047 is ExecutionException -> { 2048 Slog.e(LOG_TAG, "Cannot create permission backup for user $userId", e) 2049 null 2050 } 2051 else -> throw e 2052 } 2053 } 2054 } 2055 2056 override fun restoreRuntimePermissions(backup: ByteArray, userId: Int) { 2057 requireNotNull(backup) { "backup" } 2058 Preconditions.checkArgumentNonnegative(userId, "userId") 2059 2060 synchronized(isDelayedPermissionBackupFinished) { 2061 isDelayedPermissionBackupFinished -= userId 2062 } 2063 permissionControllerManager.stageAndApplyRuntimePermissionsBackup( 2064 backup, 2065 UserHandle.of(userId) 2066 ) 2067 } 2068 2069 override fun restoreDelayedRuntimePermissions(packageName: String, userId: Int) { 2070 requireNotNull(packageName) { "packageName" } 2071 Preconditions.checkArgumentNonnegative(userId, "userId") 2072 2073 synchronized(isDelayedPermissionBackupFinished) { 2074 if (isDelayedPermissionBackupFinished.get(userId, false)) { 2075 return 2076 } 2077 } 2078 permissionControllerManager.applyStagedRuntimePermissionBackup( 2079 packageName, 2080 UserHandle.of(userId), 2081 PermissionThread.getExecutor() 2082 ) { hasMoreBackup -> 2083 if (hasMoreBackup) { 2084 return@applyStagedRuntimePermissionBackup 2085 } 2086 synchronized(isDelayedPermissionBackupFinished) { 2087 isDelayedPermissionBackupFinished.put(userId, true) 2088 } 2089 } 2090 } 2091 2092 override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>?) { 2093 if (!DumpUtils.checkDumpPermission(context, LOG_TAG, pw)) { 2094 return 2095 } 2096 2097 val writer = IndentingPrintWriter(pw, " ") 2098 2099 if (args.isNullOrEmpty() || args[0] == "-a") { 2100 service.getState { 2101 writer.dumpSystemState(state) 2102 getAllAppIdPackageNames(state).forEachIndexed { _, appId, packageNames -> 2103 if (appId != Process.INVALID_UID) { 2104 writer.dumpAppIdState(appId, state, packageNames) 2105 } 2106 } 2107 } 2108 } else if (args[0] == "--app-id" && args.size == 2) { 2109 val appId = args[1].toInt() 2110 service.getState { 2111 val appIdPackageNames = getAllAppIdPackageNames(state) 2112 if (appId in appIdPackageNames) { 2113 writer.dumpAppIdState(appId, state, appIdPackageNames[appId]) 2114 } else { 2115 writer.println("Unknown app ID $appId.") 2116 } 2117 } 2118 } else if (args[0] == "--package" && args.size == 2) { 2119 val packageName = args[1] 2120 service.getState { 2121 val packageState = state.externalState.packageStates[packageName] 2122 if (packageState != null) { 2123 writer.dumpAppIdState(packageState.appId, state, indexedSetOf(packageName)) 2124 } else { 2125 writer.println("Unknown package $packageName.") 2126 } 2127 } 2128 } else { 2129 writer.println( 2130 "Usage: dumpsys permissionmgr [--app-id <APP_ID>] [--package <PACKAGE_NAME>]" 2131 ) 2132 } 2133 } 2134 2135 private fun getAllAppIdPackageNames( 2136 state: AccessState 2137 ): IndexedMap<Int, MutableIndexedSet<String>> { 2138 val appIds = MutableIndexedSet<Int>() 2139 2140 val packageStates = packageManagerLocal.withUnfilteredSnapshot().use { it.packageStates } 2141 state.userStates.forEachIndexed { _, _, userState -> 2142 userState.appIdPermissionFlags.forEachIndexed { _, appId, _ -> appIds.add(appId) } 2143 userState.appIdAppOpModes.forEachIndexed { _, appId, _ -> appIds.add(appId) } 2144 userState.packageVersions.forEachIndexed packageVersions@{ _, packageName, _ -> 2145 val appId = packageStates[packageName]?.appId ?: return@packageVersions 2146 appIds.add(appId) 2147 } 2148 userState.packageAppOpModes.forEachIndexed packageAppOpModes@{ _, packageName, _ -> 2149 val appId = packageStates[packageName]?.appId ?: return@packageAppOpModes 2150 appIds.add(appId) 2151 } 2152 } 2153 2154 val appIdPackageNames = MutableIndexedMap<Int, MutableIndexedSet<String>>() 2155 packageStates.forEach { (_, packageState) -> 2156 if (packageState.isApex) { 2157 return@forEach 2158 } 2159 appIdPackageNames 2160 .getOrPut(packageState.appId) { MutableIndexedSet() } 2161 .add(packageState.packageName) 2162 } 2163 // add non-package app IDs which might not be reported by package manager. 2164 appIds.forEachIndexed { _, appId -> 2165 appIdPackageNames.getOrPut(appId) { MutableIndexedSet() } 2166 } 2167 2168 return appIdPackageNames 2169 } 2170 2171 private fun IndentingPrintWriter.dumpSystemState(state: AccessState) { 2172 println("Permissions:") 2173 withIndent { 2174 state.systemState.permissions.forEachIndexed { _, _, permission -> 2175 val protectionLevel = PermissionInfo.protectionToString(permission.protectionLevel) 2176 println( 2177 "${permission.name}: " + 2178 "type=${Permission.typeToString(permission.type)}, " + 2179 "packageName=${permission.packageName}, " + 2180 "appId=${permission.appId}, " + 2181 "gids=${permission.gids.contentToString()}, " + 2182 "protectionLevel=[$protectionLevel], " + 2183 "flags=${PermissionInfo.flagsToString(permission.permissionInfo.flags)}" 2184 ) 2185 } 2186 } 2187 2188 println("Permission groups:") 2189 withIndent { 2190 state.systemState.permissionGroups.forEachIndexed { _, _, permissionGroup -> 2191 println("${permissionGroup.name}: " + "packageName=${permissionGroup.packageName}") 2192 } 2193 } 2194 2195 println("Permission trees:") 2196 withIndent { 2197 state.systemState.permissionTrees.forEachIndexed { _, _, permissionTree -> 2198 println( 2199 "${permissionTree.name}: " + 2200 "packageName=${permissionTree.packageName}, " + 2201 "appId=${permissionTree.appId}" 2202 ) 2203 } 2204 } 2205 } 2206 2207 private fun IndentingPrintWriter.dumpAppIdState( 2208 appId: Int, 2209 state: AccessState, 2210 packageNames: IndexedSet<String>? 2211 ) { 2212 println("App ID: $appId") 2213 withIndent { 2214 state.userStates.forEachIndexed { _, userId, userState -> 2215 println("User: $userId") 2216 withIndent { 2217 println("Permissions:") 2218 withIndent { 2219 userState.appIdPermissionFlags[appId]?.forEachIndexed { 2220 _, 2221 permissionName, 2222 flags -> 2223 val isGranted = PermissionFlags.isPermissionGranted(flags) 2224 println( 2225 "$permissionName: granted=$isGranted, flags=" + 2226 PermissionFlags.toString(flags) 2227 ) 2228 } 2229 } 2230 2231 userState.appIdDevicePermissionFlags[appId]?.forEachIndexed { 2232 _, 2233 deviceId, 2234 devicePermissionFlags -> 2235 println("Permissions (Device $deviceId):") 2236 withIndent { 2237 devicePermissionFlags.forEachIndexed { _, permissionName, flags -> 2238 val isGranted = PermissionFlags.isPermissionGranted(flags) 2239 println( 2240 "$permissionName: granted=$isGranted, flags=" + 2241 PermissionFlags.toString(flags) 2242 ) 2243 } 2244 } 2245 } 2246 2247 println("App ops:") 2248 withIndent { 2249 userState.appIdAppOpModes[appId]?.forEachIndexed { _, appOpName, appOpMode 2250 -> 2251 println("$appOpName: mode=${AppOpsManager.modeToName(appOpMode)}") 2252 } 2253 } 2254 2255 packageNames?.forEachIndexed { _, packageName -> 2256 println("Package: $packageName") 2257 withIndent { 2258 println("version=${userState.packageVersions[packageName]}") 2259 println("App ops:") 2260 withIndent { 2261 userState.packageAppOpModes[packageName]?.forEachIndexed { 2262 _, 2263 appOpName, 2264 appOpMode -> 2265 val modeName = AppOpsManager.modeToName(appOpMode) 2266 println("$appOpName: mode=$modeName") 2267 } 2268 } 2269 } 2270 } 2271 } 2272 } 2273 } 2274 } 2275 2276 private inline fun IndentingPrintWriter.withIndent(block: IndentingPrintWriter.() -> Unit) { 2277 increaseIndent() 2278 block() 2279 decreaseIndent() 2280 } 2281 2282 override fun getPermissionTEMP(permissionName: String): LegacyPermission2? { 2283 val permission = 2284 service.getState { with(policy) { getPermissions()[permissionName] } } ?: return null 2285 2286 return LegacyPermission2( 2287 permission.permissionInfo, 2288 permission.type, 2289 permission.isReconciled, 2290 permission.appId, 2291 permission.gids, 2292 permission.areGidsPerUser 2293 ) 2294 } 2295 2296 override fun getLegacyPermissions(): List<LegacyPermission> = 2297 service 2298 .getState { with(policy) { getPermissions() } } 2299 .mapIndexedTo(ArrayList()) { _, _, permission -> 2300 LegacyPermission( 2301 permission.permissionInfo, 2302 permission.type, 2303 permission.appId, 2304 permission.gids 2305 ) 2306 } 2307 2308 override fun readLegacyPermissionsTEMP(legacyPermissionSettings: LegacyPermissionSettings) { 2309 // Package settings has been read when this method is called. 2310 service.initialize() 2311 } 2312 2313 override fun writeLegacyPermissionsTEMP(legacyPermissionSettings: LegacyPermissionSettings) { 2314 service.getState { 2315 val permissions = with(policy) { getPermissions() } 2316 legacyPermissionSettings.replacePermissions(toLegacyPermissions(permissions)) 2317 val permissionTrees = with(policy) { getPermissionTrees() } 2318 legacyPermissionSettings.replacePermissionTrees(toLegacyPermissions(permissionTrees)) 2319 } 2320 } 2321 2322 private fun toLegacyPermissions( 2323 permissions: IndexedMap<String, Permission> 2324 ): List<LegacyPermission> = 2325 permissions.mapIndexedTo(ArrayList()) { _, _, permission -> 2326 // We don't need to provide UID and GIDs, which are only retrieved when dumping. 2327 LegacyPermission(permission.permissionInfo, permission.type, 0, EmptyArray.INT) 2328 } 2329 2330 override fun getLegacyPermissionState(appId: Int): LegacyPermissionState { 2331 val legacyState = LegacyPermissionState() 2332 val userIds = userManagerService.userIdsIncludingPreCreated 2333 service.getState { 2334 val permissions = with(policy) { getPermissions() } 2335 userIds.forEachIndexed { _, userId -> 2336 val permissionFlags = 2337 with(policy) { getUidPermissionFlags(appId, userId) } ?: return@forEachIndexed 2338 2339 permissionFlags.forEachIndexed permissionFlags@{ _, permissionName, flags -> 2340 val permission = permissions[permissionName] ?: return@permissionFlags 2341 val legacyPermissionState = 2342 LegacyPermissionState.PermissionState( 2343 permissionName, 2344 permission.isRuntime, 2345 PermissionFlags.isPermissionGranted(flags), 2346 PermissionFlags.toApiFlags(flags) 2347 ) 2348 legacyState.putPermissionState(legacyPermissionState, userId) 2349 } 2350 } 2351 } 2352 return legacyState 2353 } 2354 2355 override fun readLegacyPermissionStateTEMP() {} 2356 2357 override fun writeLegacyPermissionStateTEMP() {} 2358 2359 override fun getDefaultPermissionGrantFingerprint(userId: Int): String? = 2360 service.getState { state.userStates[userId]!!.defaultPermissionGrantFingerprint } 2361 2362 override fun setDefaultPermissionGrantFingerprint(fingerprint: String, userId: Int) { 2363 service.mutateState { 2364 newState.mutateUserState(userId)!!.setDefaultPermissionGrantFingerprint(fingerprint) 2365 } 2366 } 2367 2368 override fun onSystemReady() { 2369 service.onSystemReady() 2370 2371 virtualDeviceManagerInternal = 2372 LocalServices.getService(VirtualDeviceManagerInternal::class.java) 2373 virtualDeviceManagerInternal?.allPersistentDeviceIds?.let { persistentDeviceIds -> 2374 service.mutateState { 2375 with(devicePolicy) { trimDevicePermissionStates(persistentDeviceIds) } 2376 } 2377 } 2378 virtualDeviceManagerInternal?.registerPersistentDeviceIdRemovedListener { deviceId -> 2379 service.mutateState { with(devicePolicy) { onDeviceIdRemoved(deviceId) } } 2380 } 2381 2382 permissionControllerManager = 2383 PermissionControllerManager(context, PermissionThread.getHandler()) 2384 } 2385 2386 override fun onUserCreated(userId: Int) { 2387 withCorkedPackageInfoCache { service.onUserAdded(userId) } 2388 } 2389 2390 override fun onUserRemoved(userId: Int) { 2391 service.onUserRemoved(userId) 2392 } 2393 2394 override fun onStorageVolumeMounted(volumeUuid: String, fingerprintChanged: Boolean) { 2395 val packageNames: List<String> 2396 synchronized(storageVolumeLock) { 2397 // Removing the storageVolumePackageNames entry because we expect onPackageAdded() 2398 // to always be called before onStorageVolumeMounted(). 2399 packageNames = storageVolumePackageNames.remove(volumeUuid) ?: emptyList() 2400 mountedStorageVolumes += volumeUuid 2401 } 2402 withCorkedPackageInfoCache { 2403 service.onStorageVolumeMounted(volumeUuid, packageNames, fingerprintChanged) 2404 } 2405 } 2406 2407 override fun onPackageAdded( 2408 packageState: PackageState, 2409 isInstantApp: Boolean, 2410 oldPackage: AndroidPackage? 2411 ) { 2412 if (packageState.isApex) { 2413 return 2414 } 2415 2416 synchronized(storageVolumeLock) { 2417 // Accumulating the package names here because we want to maintain the same call order 2418 // of onPackageAdded() and reuse this order in onStorageVolumeAdded(). We need the 2419 // packages to be iterated in onStorageVolumeAdded() in the same order so that the 2420 // ownership of permissions is consistent. 2421 storageVolumePackageNames.getOrPut(packageState.volumeUuid) { mutableListOf() } += 2422 packageState.packageName 2423 if (packageState.volumeUuid !in mountedStorageVolumes) { 2424 // Wait for the storage volume to be mounted and batch the state mutation there. 2425 return 2426 } 2427 } 2428 service.onPackageAdded(packageState.packageName) 2429 } 2430 2431 override fun onPackageRemoved(androidPackage: AndroidPackage) { 2432 // This may not be a full removal so ignored - we'll figure out full removal in 2433 // onPackageUninstalled(). 2434 } 2435 2436 override fun onPackageInstalled( 2437 androidPackage: AndroidPackage, 2438 previousAppId: Int, 2439 params: PermissionManagerServiceInternal.PackageInstalledParams, 2440 userId: Int 2441 ) { 2442 if (androidPackage.isApex) { 2443 return 2444 } 2445 2446 if (params === PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT) { 2447 // TODO: We should actually stop calling onPackageInstalled() when we are passing 2448 // PackageInstalledParams.DEFAULT in InstallPackageHelper, because there's actually no 2449 // installer in those cases of system app installs, and the default params won't 2450 // allowlist any permissions which means the original UPGRADE_EXEMPT will be dropped 2451 // without any INSTALLER_EXEMPT added. However, we can't do that right now because the 2452 // old permission subsystem still depends on this method being called to set up the 2453 // permission state for the first time (which we are doing in onPackageAdded() or 2454 // onStorageVolumeMounted() now). 2455 return 2456 } 2457 2458 synchronized(storageVolumeLock) { 2459 if (androidPackage.volumeUuid !in mountedStorageVolumes) { 2460 // Wait for the storage volume to be mounted and batch the state mutation there. 2461 // PackageInstalledParams won't exist when packages are being scanned instead of 2462 // being installed by an installer. 2463 return 2464 } 2465 } 2466 val userIds = 2467 if (userId == UserHandle.USER_ALL) { 2468 userManagerService.userIdsIncludingPreCreated 2469 } else { 2470 intArrayOf(userId) 2471 } 2472 @Suppress("NAME_SHADOWING") 2473 userIds.forEach { userId -> service.onPackageInstalled(androidPackage.packageName, userId) } 2474 2475 @Suppress("NAME_SHADOWING") 2476 userIds.forEach { userId -> 2477 // TODO: Remove when this callback receives packageState directly. 2478 val packageState = 2479 packageManagerInternal.getPackageStateInternal(androidPackage.packageName)!! 2480 addAllowlistedRestrictedPermissionsUnchecked( 2481 androidPackage, 2482 packageState.appId, 2483 params.allowlistedRestrictedPermissions, 2484 userId 2485 ) 2486 setRequestedPermissionStates(packageState, userId, params.permissionStates) 2487 } 2488 } 2489 2490 override fun onPackageUninstalled( 2491 packageName: String, 2492 appId: Int, 2493 packageState: PackageState, 2494 androidPackage: AndroidPackage?, 2495 sharedUserPkgs: List<AndroidPackage>, 2496 userId: Int 2497 ) { 2498 if (packageState.isApex) { 2499 return 2500 } 2501 2502 val userIds = 2503 if (userId == UserHandle.USER_ALL) { 2504 userManagerService.userIdsIncludingPreCreated 2505 } else { 2506 intArrayOf(userId) 2507 } 2508 userIds.forEach { service.onPackageUninstalled(packageName, appId, it) } 2509 val packageState = packageManagerInternal.packageStates[packageName] 2510 if (packageState == null) { 2511 service.onPackageRemoved(packageName, appId) 2512 } 2513 } 2514 2515 private inline fun <T> withCorkedPackageInfoCache(block: () -> T): T { 2516 PackageManager.corkPackageInfoCache() 2517 try { 2518 return block() 2519 } finally { 2520 PackageManager.uncorkPackageInfoCache() 2521 } 2522 } 2523 2524 /** Check whether a UID is root or system UID. */ 2525 private fun isRootOrSystemUid(uid: Int) = 2526 when (UserHandle.getAppId(uid)) { 2527 Process.ROOT_UID, 2528 Process.SYSTEM_UID -> true 2529 else -> false 2530 } 2531 2532 /** Check whether a UID is shell UID. */ 2533 private fun isShellUid(uid: Int) = UserHandle.getAppId(uid) == Process.SHELL_UID 2534 2535 /** Check whether a UID is root, system or shell UID. */ 2536 private fun isRootOrSystemOrShellUid(uid: Int) = isRootOrSystemUid(uid) || isShellUid(uid) 2537 2538 /** 2539 * This method should typically only be used when granting or revoking permissions, since the 2540 * app may immediately restart after this call. 2541 * 2542 * If you're doing surgery on app code/data, use [PackageFreezer] to guard your work against the 2543 * app being relaunched. 2544 */ 2545 private fun killUid(uid: Int, reason: String) { 2546 val activityManager = ActivityManager.getService() 2547 if (activityManager != null) { 2548 val appId = UserHandle.getAppId(uid) 2549 val userId = UserHandle.getUserId(uid) 2550 Binder::class.withClearedCallingIdentity { 2551 try { 2552 activityManager.killUidForPermissionChange(appId, userId, reason) 2553 } catch (e: RemoteException) { 2554 /* ignore - same process */ 2555 } 2556 } 2557 } 2558 } 2559 2560 /** @see PackageManagerLocal.withFilteredSnapshot */ 2561 private fun PackageManagerLocal.withFilteredSnapshot( 2562 callingUid: Int, 2563 userId: Int 2564 ): PackageManagerLocal.FilteredSnapshot = 2565 withFilteredSnapshot(callingUid, UserHandle.of(userId)) 2566 2567 /** 2568 * Get the [PackageState] for a package name. 2569 * 2570 * This is for parity with [PackageManagerLocal.FilteredSnapshot.getPackageState] which is more 2571 * efficient than [PackageManagerLocal.FilteredSnapshot.getPackageStates], so that we can always 2572 * prefer using `getPackageState()` without worrying about whether the snapshot is filtered. 2573 */ 2574 private fun PackageManagerLocal.UnfilteredSnapshot.getPackageState( 2575 packageName: String 2576 ): PackageState? = packageStates[packageName] 2577 2578 /** Check whether a UID belongs to an instant app. */ 2579 private fun PackageManagerLocal.UnfilteredSnapshot.isUidInstantApp(uid: Int): Boolean = 2580 // Unfortunately we don't have the API for getting the owner UID of an isolated UID or the 2581 // API for getting the SharedUserApi object for an app ID yet, so for now we just keep 2582 // calling the old API. 2583 packageManagerInternal.getInstantAppPackageName(uid) != null 2584 2585 /** Check whether a package is visible to a UID within the same user as the UID. */ 2586 private fun PackageManagerLocal.UnfilteredSnapshot.isPackageVisibleToUid( 2587 packageName: String, 2588 uid: Int 2589 ): Boolean = isPackageVisibleToUid(packageName, UserHandle.getUserId(uid), uid) 2590 2591 /** Check whether a package in a particular user is visible to a UID. */ 2592 private fun PackageManagerLocal.UnfilteredSnapshot.isPackageVisibleToUid( 2593 packageName: String, 2594 userId: Int, 2595 uid: Int 2596 ): Boolean = filtered(uid, userId).use { it.getPackageState(packageName) != null } 2597 2598 /** @see PackageManagerLocal.UnfilteredSnapshot.filtered */ 2599 private fun PackageManagerLocal.UnfilteredSnapshot.filtered( 2600 callingUid: Int, 2601 userId: Int 2602 ): PackageManagerLocal.FilteredSnapshot = filtered(callingUid, UserHandle.of(userId)) 2603 2604 /** 2605 * If neither you nor the calling process of an IPC you are handling has been granted the 2606 * permission for accessing a particular [userId], throw a [SecurityException]. 2607 * 2608 * @see Context.enforceCallingOrSelfPermission 2609 * @see UserManager.DISALLOW_DEBUGGING_FEATURES 2610 */ 2611 private fun enforceCallingOrSelfCrossUserPermission( 2612 userId: Int, 2613 enforceFullPermission: Boolean, 2614 enforceShellRestriction: Boolean, 2615 message: String? 2616 ) { 2617 require(userId >= 0) { "userId $userId is invalid" } 2618 val callingUid = Binder.getCallingUid() 2619 val callingUserId = UserHandle.getUserId(callingUid) 2620 if (userId != callingUserId) { 2621 val permissionName = 2622 if (enforceFullPermission) { 2623 Manifest.permission.INTERACT_ACROSS_USERS_FULL 2624 } else { 2625 Manifest.permission.INTERACT_ACROSS_USERS 2626 } 2627 if ( 2628 context.checkCallingOrSelfPermission(permissionName) != 2629 PackageManager.PERMISSION_GRANTED 2630 ) { 2631 val exceptionMessage = buildString { 2632 if (message != null) { 2633 append(message) 2634 append(": ") 2635 } 2636 append("Neither user ") 2637 append(callingUid) 2638 append(" nor current process has ") 2639 append(permissionName) 2640 append(" to access user ") 2641 append(userId) 2642 } 2643 throw SecurityException(exceptionMessage) 2644 } 2645 } 2646 if (enforceShellRestriction && isShellUid(callingUid)) { 2647 val isShellRestricted = 2648 userManagerInternal.hasUserRestriction( 2649 UserManager.DISALLOW_DEBUGGING_FEATURES, 2650 userId 2651 ) 2652 if (isShellRestricted) { 2653 val exceptionMessage = buildString { 2654 if (message != null) { 2655 append(message) 2656 append(": ") 2657 } 2658 append("Shell is disallowed to access user ") 2659 append(userId) 2660 } 2661 throw SecurityException(exceptionMessage) 2662 } 2663 } 2664 } 2665 2666 /** 2667 * If neither you nor the calling process of an IPC you are handling has been granted any of the 2668 * permissions, throw a [SecurityException]. 2669 * 2670 * @see Context.enforceCallingOrSelfPermission 2671 */ 2672 private fun enforceCallingOrSelfAnyPermission( 2673 message: String?, 2674 vararg permissionNames: String 2675 ) { 2676 val hasAnyPermission = 2677 permissionNames.any { permissionName -> 2678 context.checkCallingOrSelfPermission(permissionName) == 2679 PackageManager.PERMISSION_GRANTED 2680 } 2681 if (!hasAnyPermission) { 2682 val exceptionMessage = buildString { 2683 if (message != null) { 2684 append(message) 2685 append(": ") 2686 } 2687 append("Neither user ") 2688 append(Binder.getCallingUid()) 2689 append(" nor current process has any of ") 2690 permissionNames.joinTo(this, ", ") 2691 } 2692 throw SecurityException(exceptionMessage) 2693 } 2694 } 2695 2696 /** Callback invoked when interesting actions have been taken on a permission. */ 2697 private inner class OnPermissionFlagsChangedListener : 2698 AppIdPermissionPolicy.OnPermissionFlagsChangedListener, 2699 DevicePermissionPolicy.OnDevicePermissionFlagsChangedListener { 2700 private var isPermissionFlagsChanged = false 2701 2702 private val runtimePermissionChangedUidDevices = MutableIntMap<MutableSet<String>>() 2703 // Mapping from UID to whether only notifications permissions are revoked. 2704 private val runtimePermissionRevokedUids = SparseBooleanArray() 2705 private val gidsChangedUids = MutableIntSet() 2706 2707 private var isKillRuntimePermissionRevokedUidsSkipped = false 2708 private val killRuntimePermissionRevokedUidsReasons = ArraySet<String>() 2709 2710 fun MutateStateScope.skipKillRuntimePermissionRevokedUids() { 2711 isKillRuntimePermissionRevokedUidsSkipped = true 2712 } 2713 2714 fun MutateStateScope.addKillRuntimePermissionRevokedUidsReason(reason: String) { 2715 killRuntimePermissionRevokedUidsReasons += reason 2716 } 2717 2718 override fun onPermissionFlagsChanged( 2719 appId: Int, 2720 userId: Int, 2721 permissionName: String, 2722 oldFlags: Int, 2723 newFlags: Int 2724 ) { 2725 onDevicePermissionFlagsChanged( 2726 appId, 2727 userId, 2728 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, 2729 permissionName, 2730 oldFlags, 2731 newFlags 2732 ) 2733 } 2734 2735 override fun onDevicePermissionFlagsChanged( 2736 appId: Int, 2737 userId: Int, 2738 deviceId: String, 2739 permissionName: String, 2740 oldFlags: Int, 2741 newFlags: Int 2742 ) { 2743 isPermissionFlagsChanged = true 2744 2745 val uid = UserHandle.getUid(userId, appId) 2746 val permission = 2747 service.getState { with(policy) { getPermissions()[permissionName] } } ?: return 2748 val wasPermissionGranted = PermissionFlags.isPermissionGranted(oldFlags) 2749 val isPermissionGranted = PermissionFlags.isPermissionGranted(newFlags) 2750 2751 if (permission.isRuntime) { 2752 // Different from the old implementation, which notifies the listeners when the 2753 // permission flags have changed for a non-runtime permission, now we no longer do 2754 // that because permission flags are only for runtime permissions and the listeners 2755 // aren't being notified of non-runtime permission grant state changes anyway. 2756 if (wasPermissionGranted && !isPermissionGranted) { 2757 runtimePermissionRevokedUids[uid] = 2758 permissionName in NOTIFICATIONS_PERMISSIONS && 2759 runtimePermissionRevokedUids.get(uid, true) 2760 } 2761 runtimePermissionChangedUidDevices.getOrPut(uid) { mutableSetOf() } += deviceId 2762 } 2763 2764 if (permission.hasGids && (wasPermissionGranted != isPermissionGranted)) { 2765 gidsChangedUids += uid 2766 } 2767 } 2768 2769 override fun onStateMutated() { 2770 if (isPermissionFlagsChanged) { 2771 PackageManager.invalidatePackageInfoCache() 2772 isPermissionFlagsChanged = false 2773 } 2774 2775 runtimePermissionChangedUidDevices.forEachIndexed { _, uid, persistentDeviceIds -> 2776 persistentDeviceIds.forEach { deviceId -> 2777 onPermissionsChangeListeners.onPermissionsChanged(uid, deviceId) 2778 } 2779 } 2780 runtimePermissionChangedUidDevices.clear() 2781 2782 if (!isKillRuntimePermissionRevokedUidsSkipped) { 2783 val reason = 2784 if (killRuntimePermissionRevokedUidsReasons.isNotEmpty()) { 2785 killRuntimePermissionRevokedUidsReasons.joinToString(", ") 2786 } else { 2787 PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED 2788 } 2789 runtimePermissionRevokedUids.forEachIndexed { 2790 _, 2791 uid, 2792 areOnlyNotificationsPermissionsRevoked -> 2793 handler.post { 2794 if ( 2795 areOnlyNotificationsPermissionsRevoked && 2796 isAppBackupAndRestoreRunning(uid) 2797 ) { 2798 return@post 2799 } 2800 killUid(uid, reason) 2801 } 2802 } 2803 } 2804 runtimePermissionRevokedUids.clear() 2805 2806 gidsChangedUids.forEachIndexed { _, uid -> 2807 handler.post { killUid(uid, PermissionManager.KILL_APP_REASON_GIDS_CHANGED) } 2808 } 2809 gidsChangedUids.clear() 2810 2811 isKillRuntimePermissionRevokedUidsSkipped = false 2812 killRuntimePermissionRevokedUidsReasons.clear() 2813 } 2814 2815 private fun isAppBackupAndRestoreRunning(uid: Int): Boolean { 2816 if ( 2817 checkUidPermission( 2818 uid, 2819 Manifest.permission.BACKUP, 2820 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT 2821 ) != PackageManager.PERMISSION_GRANTED 2822 ) { 2823 return false 2824 } 2825 2826 val userId = UserHandle.getUserId(uid) 2827 2828 val isInSetup = getSecureInt(Settings.Secure.USER_SETUP_COMPLETE, userId) == 0 2829 if (isInSetup) return true 2830 2831 val isInDeferredSetup = 2832 getSecureInt(Settings.Secure.USER_SETUP_PERSONALIZATION_STATE, userId) == 2833 Settings.Secure.USER_SETUP_PERSONALIZATION_STARTED 2834 return isInDeferredSetup 2835 } 2836 2837 private fun getSecureInt(settingName: String, userId: Int): Int? = 2838 try { 2839 Settings.Secure.getIntForUser(context.contentResolver, settingName, userId) 2840 } catch (e: Settings.SettingNotFoundException) { 2841 Slog.i(LOG_TAG, "Setting $settingName not found", e) 2842 null 2843 } 2844 } 2845 2846 private class OnPermissionsChangeListeners(looper: Looper) : Handler(looper) { 2847 private val listeners = RemoteCallbackList<IOnPermissionsChangeListener>() 2848 2849 override fun handleMessage(msg: Message) { 2850 when (msg.what) { 2851 MSG_ON_PERMISSIONS_CHANGED -> { 2852 val uid = msg.arg1 2853 val deviceId = msg.obj as String 2854 handleOnPermissionsChanged(uid, deviceId) 2855 } 2856 } 2857 } 2858 2859 private fun handleOnPermissionsChanged(uid: Int, deviceId: String) { 2860 listeners.broadcast { listener -> 2861 try { 2862 listener.onPermissionsChanged(uid, deviceId) 2863 } catch (e: RemoteException) { 2864 Slog.e(LOG_TAG, "Error when calling OnPermissionsChangeListener", e) 2865 } 2866 } 2867 } 2868 2869 fun addListener(listener: IOnPermissionsChangeListener) { 2870 listeners.register(listener) 2871 } 2872 2873 fun removeListener(listener: IOnPermissionsChangeListener) { 2874 listeners.unregister(listener) 2875 } 2876 2877 fun onPermissionsChanged(uid: Int, deviceId: String) { 2878 if (listeners.registeredCallbackCount > 0) { 2879 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0, deviceId).sendToTarget() 2880 } 2881 } 2882 2883 companion object { 2884 private const val MSG_ON_PERMISSIONS_CHANGED = 1 2885 } 2886 } 2887 2888 companion object { 2889 private val LOG_TAG = PermissionService::class.java.simpleName 2890 2891 /** 2892 * This change makes it so that apps are told to show rationale for asking for background 2893 * location access every time they request. 2894 */ 2895 @ChangeId 2896 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) 2897 private val BACKGROUND_RATIONALE_CHANGE_ID = 147316723L 2898 2899 private val FULLER_PERMISSIONS = 2900 ArrayMap<String, String>().apply { 2901 this[Manifest.permission.ACCESS_COARSE_LOCATION] = 2902 Manifest.permission.ACCESS_FINE_LOCATION 2903 this[Manifest.permission.INTERACT_ACROSS_USERS] = 2904 Manifest.permission.INTERACT_ACROSS_USERS_FULL 2905 } 2906 2907 private val NOTIFICATIONS_PERMISSIONS = arraySetOf(Manifest.permission.POST_NOTIFICATIONS) 2908 2909 private const val REVIEW_REQUIRED_FLAGS = 2910 PermissionFlags.LEGACY_GRANTED or PermissionFlags.IMPLICIT 2911 private const val UNREQUESTABLE_MASK = 2912 PermissionFlags.RESTRICTION_REVOKED or 2913 PermissionFlags.SYSTEM_FIXED or 2914 PermissionFlags.POLICY_FIXED or 2915 PermissionFlags.USER_FIXED 2916 2917 private val BACKUP_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(60) 2918 2919 /** 2920 * Cap the size of permission trees that 3rd party apps can define; in characters of text 2921 */ 2922 private const val MAX_PERMISSION_TREE_FOOTPRINT = 32768 2923 2924 private const val PERMISSION_ALLOWLIST_MASK = 2925 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE or 2926 PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM or 2927 PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER 2928 2929 fun getFullerPermission(permissionName: String): String? = 2930 FULLER_PERMISSIONS[permissionName] 2931 } 2932 } 2933