CVE-2026-28578 AI-generated analysis
platform/frameworks/base, services/devicepolicy (DevicePolicyManagerService, PackagePolicy setters)
Adds a per-package-name length check (enforcePackagePolicyPackageNamesLength) to the three DevicePolicyManagerService setters that accept a PackagePolicy (managed profile caller-id/contacts access policies and credential manager policy), rejecting overlong package names before the policy is processed.
Root cause
The DevicePolicyManagerService setters that take a PackagePolicy did not check the length of the strings returned by policy.getPackageNames(). Two of them are guarded by isProfileOwner(caller) && isManagedProfile(caller.getUserId()); the credential manager policy setter is guarded by canWriteCredentialManagerPolicy(caller). As a result, a supplied policy could carry package names longer than MAX_PACKAGE_NAME_LENGTH into the service. The bulletin rates this as a High-severity DoS; the material does not show the failure mode downstream.
How the fix works
- services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java: new private helper enforcePackagePolicyPackageNamesLength(@NonNull PackagePolicy policy) loops over policy.getPackageNames() and skips null entries. On Android 14 it calls Preconditions.checkArgument(pkg.length() <= MAX_PACKAGE_NAME_LENGTH, "Package name too long"); on 15/16/17 it calls PolicySizeVerifier.enforceMaxPackageNameLength(pkg).
- The helper is called in three setters, each time right after the `if (!mHasFeature) return;` early exit and before getCallerIdentity() and the authorization check. Two are the managed-profile setters (context: Preconditions.checkCallAuthorization(isProfileOwner(caller) && isManagedProfile(caller.getUserId()))). The third is the credential manager policy setter (context: Preconditions.checkCallAuthorization(canWriteCredentialManagerPolicy(caller))), located just before getCredentialManagerPolicy. Each call is guarded by `if (policy != null)`, so a null policy skips the check.
- Per the commit message, the targeted APIs are the managed profile contacts access policy, the caller-id access policy (named in the tests) and the credential manager policy. The diff hunks do not show the setter method names.
Completeness
- Covers exactly three PackagePolicy entry points in DevicePolicyManagerService. This diff does not touch any other path that ingests a PackagePolicy, and the material does not show whether such paths exist.
- Only the length of each string is checked. This change does not bound the number of entries in getPackageNames(), and null entries are skipped rather than rejected.
- A null PackagePolicy bypasses the helper.
- The length check runs before the caller authorization check; the existing authorization check is unchanged.
Behavior changes
- The three setters now reject a PackagePolicy that contains any package name over the maximum length. On Android 14 this is an IllegalArgumentException ("Package name too long") from Preconditions.checkArgument; on 15+ the rejection comes from PolicySizeVerifier.enforceMaxPackageNameLength.
- When mHasFeature is false, the setters still return silently before any validation.
Per major
- Android 14: adapted fix: commit 1d7703a6b66d in android-security-14.0.0_r28. Same three call sites, but the helper uses Preconditions.checkArgument(pkg.length() <= MAX_PACKAGE_NAME_LENGTH, ...) instead of PolicySizeVerifier. 8/8 lines present at android-security-14.0.0_r29.
- Android 15: same fix as 17: commit e8ff8af05575 in android-security-15.0.0_r16; the helper calls PolicySizeVerifier.enforceMaxPackageNameLength(pkg). 8/8 lines present at android-security-15.0.0_r17.
- Android 16: same fix as 17: commit 48c17df8bdc4 in android-security-16.0.0_r7; the helper calls PolicySizeVerifier.enforceMaxPackageNameLength(pkg). 8/8 lines present at android-security-16.0.0_r8.
- Android 17: base fix: commit 4914d6e98bd2 in android-17.0.0_r1 (the authorization context uses mDeviceAdmins.isProfileOwner(caller)). 8/8 lines present at android-security-17.0.0_r1.
Unknowns
- The exact names of the three patched setter methods (hunk headers only show the class; the names are inferred from the commit message and tests).
- The concrete downstream failure behind the DoS, including whether the policy is persisted.
- Whether other PackagePolicy ingestion paths in DevicePolicyManagerService remain unchecked.
- The value of MAX_PACKAGE_NAME_LENGTH, what PolicySizeVerifier.enforceMaxPackageNameLength throws, and whether PolicySizeVerifier exists on the Android 14 branch.