1 /* 2 * Copyright (C) 2021 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.app.AppOpsManager 20 import android.app.admin.DevicePolicyManager 21 import android.content.pm.PackageManager 22 import android.os.Build 23 import android.permission.PermissionManager 24 import com.android.server.permission.access.util.andInv 25 import com.android.server.permission.access.util.hasAnyBit 26 import com.android.server.permission.access.util.hasBits 27 28 /** 29 * A set of internal permission flags that's better than the set of `FLAG_PERMISSION_*` constants on 30 * [PackageManager]. 31 * 32 * The old binary permission state is now tracked by multiple `*_GRANTED` and `*_REVOKED` flags, so 33 * that: 34 * 35 * - With [INSTALL_GRANTED] and [INSTALL_REVOKED], we can now get rid of the old per-package 36 * `areInstallPermissionsFixed` attribute and correctly track it per-permission, finally fixing 37 * edge cases during module rollbacks. 38 * 39 * - With [LEGACY_GRANTED] and [IMPLICIT_GRANTED], we can now ensure that legacy permissions and 40 * implicit permissions split from non-runtime permissions are never revoked, without checking 41 * split permissions and package state everywhere slowly and in slightly different ways. 42 * 43 * - With [RESTRICTION_REVOKED], we can now get rid of the error-prone logic about revoking and 44 * potentially re-granting permissions upon restriction state changes. 45 * 46 * Permission grants due to protection level are now tracked by [PROTECTION_GRANTED], and permission 47 * grants due to [PackageManager.grantRuntimePermission] are now tracked by [RUNTIME_GRANTED]. 48 * 49 * The [PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED] and 50 * [PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED] flags are now unified into [IMPLICIT], and 51 * they can be differentiated by the presence of [LEGACY_GRANTED]. 52 * 53 * The rest of the permission flags have a 1:1 mapping to the old `FLAG_PERMISSION_*` constants, and 54 * don't have any effect on the binary permission state. 55 */ 56 object PermissionFlags { 57 /** 58 * Permission flag for a normal permission that is granted at package installation. 59 */ 60 const val INSTALL_GRANTED = 1 shl 0 61 62 /** 63 * Permission flag for a normal permission that is revoked at package installation. 64 * 65 * Normally packages that have already been installed cannot be granted new normal permissions 66 * until its next installation (update), so this flag helps track that the normal permission was 67 * revoked upon its most recent installation. 68 */ 69 const val INSTALL_REVOKED = 1 shl 1 70 71 /** 72 * Permission flag for a signature or internal permission that is granted based on the 73 * permission's protection level, including its protection and protection flags. 74 * 75 * For example, this flag may be set when the permission is a signature permission and the 76 * package is having a compatible signing certificate with the package defining the permission, 77 * or when the permission is a privileged permission and the package is a privileged app with 78 * its permission in the 79 * [privileged permission allowlist](https://source.android.com/docs/core/permissions/perms-allowlist). 80 */ 81 const val PROTECTION_GRANTED = 1 shl 2 82 83 /** 84 * Permission flag for a role or runtime permission that is or was granted by a role. 85 * 86 * @see PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE 87 */ 88 const val ROLE = 1 shl 3 89 90 /** 91 * Permission flag for a development, role or runtime permission that is granted via 92 * [PackageManager.grantRuntimePermission]. 93 */ 94 const val RUNTIME_GRANTED = 1 shl 4 95 96 /** 97 * Permission flag for a runtime permission whose state is set by the user. 98 * 99 * For example, this flag may be set when the permission is allowed by the user in the 100 * request permission dialog, or managed in the permission settings. 101 * 102 * @see PackageManager.FLAG_PERMISSION_USER_SET 103 */ 104 const val USER_SET = 1 shl 5 105 106 /** 107 * Permission flag for a runtime permission whose state is (revoked and) fixed by the user. 108 * 109 * For example, this flag may be set when the permission is denied twice by the user in the 110 * request permission dialog. 111 * 112 * @see PackageManager.FLAG_PERMISSION_USER_FIXED 113 */ 114 const val USER_FIXED = 1 shl 6 115 116 /** 117 * Permission flag for a runtime permission whose state is set and fixed by the device policy 118 * via [DevicePolicyManager.setPermissionGrantState]. 119 * 120 * @see PackageManager.FLAG_PERMISSION_POLICY_FIXED 121 */ 122 const val POLICY_FIXED = 1 shl 7 123 124 /** 125 * Permission flag for a runtime permission that is (pregranted and) fixed by the system. 126 * 127 * For example, this flag may be set in 128 * [com.android.server.pm.permission.DefaultPermissionGrantPolicy]. 129 * 130 * @see PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 131 */ 132 const val SYSTEM_FIXED = 1 shl 8 133 134 /** 135 * Permission flag for a runtime permission that is or was pregranted by the system. 136 * 137 * For example, this flag may be set in 138 * [com.android.server.pm.permission.DefaultPermissionGrantPolicy]. 139 * 140 * @see PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 141 */ 142 const val PREGRANT = 1 shl 9 143 144 /** 145 * Permission flag for a runtime permission that is granted because the package targets a legacy 146 * SDK version before [Build.VERSION_CODES.M] and doesn't support runtime permissions. 147 * 148 * As long as this flag is set, the permission should always be considered granted, although 149 * [APP_OP_REVOKED] may cause the app op for the runtime permission to be revoked. Once the 150 * package targets a higher SDK version so that it started supporting runtime permissions, this 151 * flag should be removed and the remaining flags should take effect. 152 * 153 * @see PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 154 * @see PackageManager.FLAG_PERMISSION_REVOKED_COMPAT 155 */ 156 const val LEGACY_GRANTED = 1 shl 10 157 158 /** 159 * Permission flag for a runtime permission that is granted because the package targets a lower 160 * SDK version and the permission is implicit to it as a 161 * [split permission][PermissionManager.SplitPermissionInfo] from other non-runtime permissions. 162 * 163 * As long as this flag is set, the permission should always be considered granted, although 164 * [APP_OP_REVOKED] may cause the app op for the runtime permission to be revoked. Once the 165 * package targets a higher SDK version so that the permission is no longer implicit to it, this 166 * flag should be removed and the remaining flags should take effect. 167 * 168 * @see PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED 169 * @see PackageManager.FLAG_PERMISSION_REVOKED_COMPAT 170 */ 171 const val IMPLICIT_GRANTED = 1 shl 11 172 173 /** 174 * Permission flag for a runtime permission that is granted because the package targets a legacy 175 * SDK version before [Build.VERSION_CODES.M] and doesn't support runtime permissions, so that 176 * it needs to be reviewed by the user; or granted because the package targets a lower SDK 177 * version and the permission is implicit to it as a 178 * [split permission][PermissionManager.SplitPermissionInfo] from other non-runtime permissions, 179 * so that it needs to be revoked when it's no longer implicit. 180 * 181 * @see PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 182 * @see PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED 183 */ 184 const val IMPLICIT = 1 shl 12 185 186 /** 187 * Permission flag for a runtime permission that is user-sensitive when it's granted. 188 * 189 * This flag is informational and managed by PermissionController. 190 * 191 * @see PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED 192 */ 193 const val USER_SENSITIVE_WHEN_GRANTED = 1 shl 13 194 195 /** 196 * Permission flag for a runtime permission that is user-sensitive when it's revoked. 197 * 198 * This flag is informational and managed by PermissionController. 199 * 200 * @see PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED 201 */ 202 const val USER_SENSITIVE_WHEN_REVOKED = 1 shl 14 203 204 /** 205 * Permission flag for a restricted runtime permission that is exempt by the package's 206 * installer. 207 * 208 * For example, this flag may be set when the installer applied the exemption as part of the 209 * [session parameters](https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(java.util.Set%3Cjava.lang.String%3E)). 210 * 211 * The permission will be restricted when none of the exempt flags is set. 212 * 213 * @see PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT 214 */ 215 const val INSTALLER_EXEMPT = 1 shl 15 216 217 /** 218 * Permission flag for a restricted runtime permission that is exempt by the system. 219 * 220 * For example, this flag may be set when the package is a system app. 221 * 222 * The permission will be restricted when none of the exempt flags is set. 223 * 224 * @see PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT 225 */ 226 const val SYSTEM_EXEMPT = 1 shl 16 227 228 /** 229 * Permission flag for a restricted runtime permission that is exempt due to system upgrade. 230 * 231 * For example, this flag may be set when the package was installed before the system was 232 * upgraded to [Build.VERSION_CODES.Q], when restricted permissions were introduced. 233 * 234 * The permission will be restricted when none of the exempt flags is set. 235 * 236 * @see PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT 237 */ 238 const val UPGRADE_EXEMPT = 1 shl 17 239 240 /** 241 * Permission flag for a restricted runtime permission that is revoked due to being hard 242 * restricted. 243 * 244 * @see PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION 245 */ 246 const val RESTRICTION_REVOKED = 1 shl 18 247 248 /** 249 * Permission flag for a restricted runtime permission that is soft restricted. 250 * 251 * @see PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION 252 */ 253 const val SOFT_RESTRICTED = 1 shl 19 254 255 /** 256 * Permission flag for a runtime permission whose app op is revoked. 257 * 258 * For example, this flag may be set when the runtime permission is legacy or implicit but still 259 * "revoked" by the user in permission settings, or when the app op mode for the runtime 260 * permission is set to revoked via [AppOpsManager.setUidMode]. 261 * 262 * @see PackageManager.FLAG_PERMISSION_REVOKED_COMPAT 263 */ 264 const val APP_OP_REVOKED = 1 shl 20 265 266 /** 267 * Permission flag for a runtime permission that is granted as one-time. 268 * 269 * For example, this flag may be set when the user selected "Only this time" in the request 270 * permission dialog. 271 * 272 * This flag, along with other user decisions when it is set, should never be persisted, and 273 * should be removed once the permission is revoked. 274 * 275 * @see PackageManager.FLAG_PERMISSION_ONE_TIME 276 */ 277 const val ONE_TIME = 1 shl 21 278 279 /** 280 * Permission flag for a runtime permission that was revoked due to app hibernation. 281 * 282 * This flag is informational and added by PermissionController, and should be removed once the 283 * permission is granted again. 284 * 285 * @see PackageManager.FLAG_PERMISSION_AUTO_REVOKED 286 */ 287 const val HIBERNATION = 1 shl 22 288 289 /** 290 * Permission flag for a runtime permission that is selected by the user. 291 * 292 * For example, this flag may be set when one of the coarse/fine location accuracies is 293 * selected by the user. 294 * 295 * This flag is informational and managed by PermissionController. 296 * 297 * @see PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY 298 */ 299 const val USER_SELECTED = 1 shl 23 300 301 /** 302 * Mask for all permission flags. 303 */ 304 const val MASK_ALL = 0.inv() 305 306 /** 307 * Mask for all permission flags that may be applied to a runtime permission. 308 */ 309 const val MASK_RUNTIME = ROLE or RUNTIME_GRANTED or USER_SET or USER_FIXED or POLICY_FIXED or 310 SYSTEM_FIXED or PREGRANT or LEGACY_GRANTED or IMPLICIT_GRANTED or IMPLICIT or 311 USER_SENSITIVE_WHEN_GRANTED or USER_SENSITIVE_WHEN_REVOKED or INSTALLER_EXEMPT or 312 SYSTEM_EXEMPT or UPGRADE_EXEMPT or RESTRICTION_REVOKED or SOFT_RESTRICTED or 313 APP_OP_REVOKED or ONE_TIME or HIBERNATION or USER_SELECTED 314 315 /** 316 * Mask for all permission flags about permission exemption. 317 */ 318 const val MASK_EXEMPT = INSTALLER_EXEMPT or SYSTEM_EXEMPT or UPGRADE_EXEMPT 319 320 fun isPermissionGranted(flags: Int): Boolean { 321 if (flags.hasBits(INSTALL_GRANTED)) { 322 return true 323 } 324 if (flags.hasBits(INSTALL_REVOKED)) { 325 return false 326 } 327 if (flags.hasBits(PROTECTION_GRANTED)) { 328 return true 329 } 330 if (flags.hasBits(LEGACY_GRANTED) || flags.hasBits(IMPLICIT_GRANTED)) { 331 return true 332 } 333 if (flags.hasBits(RESTRICTION_REVOKED)) { 334 return false 335 } 336 return flags.hasBits(RUNTIME_GRANTED) 337 } 338 339 fun isAppOpGranted(flags: Int): Boolean = 340 isPermissionGranted(flags) && !flags.hasBits(APP_OP_REVOKED) 341 342 fun toApiFlags(flags: Int): Int { 343 var apiFlags = 0 344 if (flags.hasBits(USER_SET)) { 345 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_SET 346 } 347 if (flags.hasBits(USER_FIXED)) { 348 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_FIXED 349 } 350 if (flags.hasBits(POLICY_FIXED)) { 351 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_POLICY_FIXED 352 } 353 if (flags.hasBits(SYSTEM_FIXED)) { 354 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 355 } 356 if (flags.hasBits(PREGRANT)) { 357 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT 358 } 359 if (flags.hasBits(IMPLICIT)) { 360 apiFlags = apiFlags or if (flags.hasBits(LEGACY_GRANTED)) { 361 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 362 } else { 363 PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED 364 } 365 } 366 if (flags.hasBits(USER_SENSITIVE_WHEN_GRANTED)) { 367 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED 368 } 369 if (flags.hasBits(USER_SENSITIVE_WHEN_REVOKED)) { 370 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED 371 } 372 if (flags.hasBits(INSTALLER_EXEMPT)) { 373 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT 374 } 375 if (flags.hasBits(SYSTEM_EXEMPT)) { 376 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT 377 } 378 if (flags.hasBits(UPGRADE_EXEMPT)) { 379 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT 380 } 381 if (flags.hasBits(RESTRICTION_REVOKED) || flags.hasBits(SOFT_RESTRICTED)) { 382 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION 383 } 384 if (flags.hasBits(ROLE)) { 385 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE 386 } 387 if (flags.hasBits(APP_OP_REVOKED)) { 388 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_REVOKED_COMPAT 389 } 390 if (flags.hasBits(ONE_TIME)) { 391 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_ONE_TIME 392 } 393 if (flags.hasBits(HIBERNATION)) { 394 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_AUTO_REVOKED 395 } 396 if (flags.hasBits(USER_SELECTED)) { 397 apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY 398 } 399 return apiFlags 400 } 401 402 fun updateRuntimePermissionGranted(flags: Int, isGranted: Boolean): Int = 403 if (isGranted) flags or RUNTIME_GRANTED else flags andInv RUNTIME_GRANTED 404 405 fun updateFlags(permission: Permission, flags: Int, apiFlagMask: Int, apiFlagValues: Int): Int { 406 val oldApiFlags = toApiFlags(flags) 407 val newApiFlags = (oldApiFlags andInv apiFlagMask) or (apiFlagValues and apiFlagMask) 408 return fromApiFlags(newApiFlags, permission, flags) 409 } 410 411 private fun fromApiFlags(apiFlags: Int, permission: Permission, oldFlags: Int): Int { 412 var flags = 0 413 flags = flags or (oldFlags and INSTALL_GRANTED) 414 flags = flags or (oldFlags and INSTALL_REVOKED) 415 flags = flags or (oldFlags and PROTECTION_GRANTED) 416 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE)) { 417 flags = flags or ROLE 418 } 419 flags = flags or (oldFlags and RUNTIME_GRANTED) 420 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_SET)) { 421 flags = flags or USER_SET 422 } 423 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_FIXED)) { 424 flags = flags or USER_FIXED 425 } 426 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_POLICY_FIXED)) { 427 flags = flags or POLICY_FIXED 428 } 429 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_SYSTEM_FIXED)) { 430 flags = flags or SYSTEM_FIXED 431 } 432 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT)) { 433 flags = flags or PREGRANT 434 } 435 flags = flags or (oldFlags and LEGACY_GRANTED) 436 flags = flags or (oldFlags and IMPLICIT_GRANTED) 437 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) || 438 apiFlags.hasBits(PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED)) { 439 flags = flags or IMPLICIT 440 } 441 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED)) { 442 flags = flags or USER_SENSITIVE_WHEN_GRANTED 443 } 444 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED)) { 445 flags = flags or USER_SENSITIVE_WHEN_REVOKED 446 } 447 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT)) { 448 flags = flags or INSTALLER_EXEMPT 449 } 450 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT)) { 451 flags = flags or SYSTEM_EXEMPT 452 } 453 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT)) { 454 flags = flags or UPGRADE_EXEMPT 455 } 456 // We ignore whether FLAG_PERMISSION_APPLY_RESTRICTION is set here because previously 457 // platform may be relying on the old restorePermissionState() to get it correct later. 458 if (!flags.hasAnyBit(MASK_EXEMPT)) { 459 if (permission.isHardRestricted) { 460 flags = flags or RESTRICTION_REVOKED 461 } 462 if (permission.isSoftRestricted) { 463 flags = flags or SOFT_RESTRICTED 464 } 465 } 466 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_REVOKED_COMPAT)) { 467 flags = flags or APP_OP_REVOKED 468 } 469 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_ONE_TIME)) { 470 flags = flags or ONE_TIME 471 } 472 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_AUTO_REVOKED)) { 473 flags = flags or HIBERNATION 474 } 475 if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY)) { 476 flags = flags or USER_SELECTED 477 } 478 return flags 479 } 480 } 481