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