CVE-2024-49720 AI-generated analysis
platform/packages/modules/Permission, PermissionController role-controller (com.android.role.controller.model.Permissions)
Adds PackageManager.FLAG_PERMISSION_ONE_TIME to the set of flags that the role controller treats as a user choice, so role (re-)evaluation no longer overrides a permission the user chose to grant only once, and clears that flag when a role grant gives a permission that was not previously granted.
Root cause
In PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java, the role granting logic decides whether a permission's current state is a user choice that must be respected. When overrideUserSetAndFixed is false, it tests only FLAG_PERMISSION_USER_FIXED and FLAG_PERMISSION_USER_SET. FLAG_PERMISSION_ONE_TIME, which reflects the 'ask every time' choice, was not in that set. As a result, role re-evaluation did not treat a one-time choice as a user choice and could override it (the commit message calls this the missing ONE_TIME check). Likewise, the mask applied when a role grants a previously ungranted permission cleared USER_FIXED/USER_SET but not ONE_TIME.
How the fix works
- Permissions.java, grant path (hunk at line ~249 in 14, ~258 in 15; the method that calls grantPermissionAndAppOp and then setPermissionFlags): when the permission was not previously granted (!wasPermissionOrAppOpGranted), newMask now also includes PackageManager.FLAG_PERMISSION_ONE_TIME alongside FLAG_PERMISSION_USER_FIXED and FLAG_PERMISSION_USER_SET, so a role grant clears the one-time state together with the other user-choice flags.
- Permissions.java, fixed-flags helper (hunk at line ~606 in 14, ~629 in 15; the method that builds fixedFlags based on overrideUserSetAndFixed and returns (flags & fixedFlags) != 0; the material does not show its name): when overrideUserSetAndFixed is false, fixedFlags now also includes FLAG_PERMISSION_ONE_TIME, so a permission with the one-time flag counts as fixed by user choice and the role controller does not override it.
- Single commit with two hunks in one file; no other files changed. The commit cites RolePermissionOverrideTest, which is not in the diff shown.
Completeness
- Covers both places in Permissions.java where USER_FIXED | USER_SET were used as the user-choice set: the fixed-flags check that gates overriding, and the mask applied on grant.
- Only the role-controller model is changed. The material does not show whether any other component evaluates user-choice flags with the same two-flag set, so coverage outside this file is unknown.
- When overrideUserSetAndFixed is true, the fixed-flags check does not add the user-choice flags, so ONE_TIME is still not treated as fixed in that case.
Behavior changes
- During role evaluation without user-choice override, a permission carrying FLAG_PERMISSION_ONE_TIME is now considered fixed and the role controller does not override it.
- When the role controller grants a previously ungranted permission, FLAG_PERMISSION_ONE_TIME is now cleared in the same mask update as USER_FIXED and USER_SET.
Per major
- Android 14: same fix: commit e02775c62a81 in android-security-14.0.0_r19 (cherry-pick, Change-Id Ie65c2cd62ba3f24e8dd411abca49e397746bc1a9); at android-security-14.0.0_r29, 7/8 lines of the patched region are present.
- Android 15: same fix: commit 87fda0e3b03e in android-security-15.0.0_r7, with the same two hunks at shifted line numbers (258, 629); at android-security-15.0.0_r17, 7/8 lines of the patched region are present.
- Android 16: not affected (not listed by the bulletin); at android-security-16.0.0_r8, 7/8 lines of the patched region are present.
- Android 17: not affected (not listed by the bulletin); at android-security-17.0.0_r1, 7/8 lines of the patched region are present.
Unknowns
- The material does not show the name of the method that contains the second hunk (fixedFlags / overrideUserSetAndFixed).
- The material does not show which roles use overrideUserSetAndFixed false, so it does not show which permissions or role holders were affected.
- The bulletin lists Android 13 as affected, but the material includes no Android 13 commit.
- The RolePermissionOverrideTest referenced in the commit message is not included in the diff.
- The material does not say which line of the patched region is missing in each later tag (7/8 lines present).