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