CVE-2026-0087 AI-generated analysis
platform/frameworks/base, PackageManager domain verification (services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java)
Tightens wildcard domain matching in DomainVerificationService so a verified "*.xyz.com" entry only approves the host "xyz.com" or hosts ending in ".xyz.com", instead of any host whose string ends in "xyz.com" (e.g. "abcxyz.com").
Root cause
In DomainVerificationService.java, the approval-level computation (the method containing the "host verified by wildcard" debugApproval branch; method name not shown in the material) iterates the package's verified state map and, for a key starting with "*.", approved the host with `host.endsWith(domain.substring(2))`. substring(2) strips both the "*" and the ".", so for "*.xyz.com" the comparison suffix was "xyz.com". Any host string ending in "xyz.com", including unrelated registrable domains such as "abcxyz.com", therefore satisfied the check and returned APPROVAL_LEVEL_VERIFIED for that package.
How the fix works
- DomainVerificationService.java (wildcard branch of the approval-level loop over stateMap): the condition becomes `domain.startsWith("*.") && (host.endsWith(domain.substring(1)) || host.equals(domain.substring(2)))`. substring(1) keeps the leading ".", so only true subdomains ("abc.xyz.com") match by suffix; the explicit equals(substring(2)) preserves matching of the base domain itself ("xyz.com").
- DomainVerificationPackageTest.kt: adds testWildcardDomain, which verifies a package with verified "*.xyz.com" via setStatus(STATE_SUCCESS), then asserts getOwnersForDomain("abcxyz.com") is empty while "abc.xyz.com" and "xyz.com" return DomainOwner(PKG_ONE, false).
Completeness
- Covers the single wildcard comparison in the verified-state loop of DomainVerificationService; this is the only production code line changed.
- The preceding exact-host lookup (stateMap.get(host)) and the later user-enabled-hosts path (userState.getEnabledHosts().contains(host)) are exact-match checks and are untouched; whether any other wildcard-handling code exists elsewhere (e.g. in the collector or user-state handling) is not shown in the material.
- Matching remains a plain string suffix comparison (no normalization changes); the fix only adds the separator requirement.
Behavior changes
- Hosts that end in a wildcard's suffix without a preceding "." (e.g. "abcxyz.com" for "*.xyz.com") no longer yield APPROVAL_LEVEL_VERIFIED for that package via the wildcard branch; getOwnersForDomain no longer lists the package as owner for such hosts.
- Matching of the bare base domain ("xyz.com") and of real subdomains ("abc.xyz.com") is unchanged (both matched before and still match).
Per major
- Android 14: same fix: b035d109935c in android-security-14.0.0_r28 (cherry-pick of 919d0cb125b3); 6/6 patched lines present at android-security-14.0.0_r29; test uses service.addPackage(pkg).
- Android 15: same fix (adapted test): b81e2355caf1 in android-security-15.0.0_r16; identical production change at a different offset (line ~2030); test uses service.addPackage(pkg, null); 6/6 lines present at android-security-15.0.0_r17.
- Android 16: same fix (adapted test): 2e3d71d027b0 in android-security-16.0.0_r7; identical production change at line ~2030, test uses addPackage(pkg, null); 6/6 lines present at android-security-16.0.0_r8.
- Android 17: same fix: c225d09f44e6 in android-17.0.0_r1 (base), diff identical to the Android 14 variant (line ~1887, addPackage(pkg)); 6/6 lines present at android-security-17.0.0_r1.
Unknowns
- The name of the enclosing method in DomainVerificationService that contains the wildcard branch is not shown in the material.
- The material does not show the concrete privilege-escalation consequence beyond the bulletin's EoP/High rating, nor which external callers of the approval computation (e.g. intent resolution) are affected.
- Whether wildcard domains are handled anywhere else in the domain verification code is not shown.