CVE-2024-43769 AI-generated analysis
platform/frameworks/base, PackageManagerService (device admin / DMRH check used for package protection)
Reworks PackageManagerService.isPackageDeviceAdmin so the device management role holder (DMRH) counts as an admin only on users that are organization-managed. When the DMRH is a system package, it is treated as an admin on all users whenever any user is both managed and has it as role holder. Per the commit comment, this addresses 'uninstall updates' on an unmanaged user breaking management on other users.
Root cause
In services/core/java/com/android/server/pm/PackageManagerService.java, isPackageDeviceAdmin(packageName, userId) checks whether a package counts as a device admin. For a specific userId it looped over that single user only, calling dpm.packageHasActiveAdmins and isDeviceManagementRoleHolder for that user. The DMRH check did not consider whether the user is actually organization-managed. It also did not account for a system package's APK version being shared across all users. Per the commit comment, 'uninstall updates' on an unmanaged user may therefore break management on other users.
How the fix works
- PackageManagerService.java:isPackageDeviceAdmin: also obtains DevicePolicyManagerInternal via mInjector.getLocalService(DevicePolicyManagerInternal.class) and requires both dpm != null and dpmi != null before running the checks.
- PackageManagerService.java:isPackageDeviceAdmin: splits the user loop. The active-device-admin check (dpm.packageHasActiveAdmins) still runs over targetUsers (all users for USER_ALL, otherwise the single userId).
- PackageManagerService.java:isPackageDeviceAdmin: the DMRH check moves into a separate loop. It looks up the package via snapshotComputer().getPackageStateInternal(packageName) and returns false if the state is null. If packageState.isSystem() is true it iterates over allUsers (mUserManager.getUserIds()), otherwise over targetUsers. For each user it returns true only if isDeviceManagementRoleHolder(packageName, user) AND dpmi.isUserOrganizationManaged(user).
- Net effect: a system DMRH counts as an admin on every user as long as some user is organization-managed and has it as role holder. A DMRH on a user that is not organization-managed no longer counts as an admin (commit title: allow uninstalling DMRH when not used for management).
Completeness
- The change works in both directions inside isPackageDeviceAdmin. It tightens protection of a system DMRH across users (shared APK) and loosens protection for a DMRH on users that are not managed.
- Only system packages (packageState.isSystem()) get the all-users DMRH scan. A non-system DMRH is still checked only on targetUsers, which matches the shared-APK reasoning in the commit comment.
- The device-owner/profile-owner checks earlier in the function (dpm.getDeviceOwnerComponent and the lines after it) are not changed by the diff.
- This commit does not change the callers of isPackageDeviceAdmin, and the material does not show them. Whether every uninstall-like path calls this function cannot be judged from the material.
- An existing code comment, TODO(b/261957226), asks for this logic to be centralised in DPM. This fix keeps the logic in PackageManagerService.
Behavior changes
- A package that is DMRH on a user that is not organization-managed is no longer reported as a device admin (commit title: allow uninstalling DMRH when not used for management).
- A system package that is DMRH on an organization-managed user is now reported as a device admin for every user, including unmanaged ones.
- If the DevicePolicyManagerInternal local service is unavailable, the admin/DMRH checks are skipped (before, only dpm != null was required).
- If the package has no PackageStateInternal in the snapshot, the function returns false after the active-admin loop.
- Each call now also runs mUserManager.getUserIds() and a snapshot package-state lookup, even for a single-user query.
Per major
- Android 14: same fix: commit 619ffc299bf3 is in android-security-14.0.0_r15; at android-security-14.0.0_r29 all 8 of 8 lines of the patched region are present.
- Android 15: not affected: not listed by the bulletin; at android-security-15.0.0_r17 all 8 of 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 of 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 of 8 lines of the patched region are present.
Unknowns
- The exact trigger and the privilege gained (the bulletin only states High EoP; the commit comment describes 'uninstall updates' on an unmanaged user breaking management on other users).
- Which callers of isPackageDeviceAdmin exist and are reachable (index search found no callers), and how they act on its result.
- What the function returns when dpm or dpmi is null (code after the if block is not shown).
- Content of the Android 13 fix, if any, and the exact 1-line difference in the 16/17 branches.