CVE-2025-26445 AI-generated analysis
platform/packages/modules/Connectivity, ConnectivityService (network provider / network offer binder API)
Adds a missing caller permission check to ConnectivityService.offerNetwork so that only holders of NETWORK_FACTORY/MAINLINE_NETWORK_STACK (or MANAGE_TEST_NETWORKS for TRANSPORT_TEST offers) can register a network offer.
Root cause
The binder entry point ConnectivityService.offerNetwork(providerId, score, caps, callback) only null-checked its arguments. It then posted EVENT_REGISTER_NETWORK_OFFER with a NetworkOffer built from the score, capabilities and callback that the caller supplied. The sibling entry points registerNetworkProvider and unregisterNetworkProvider call enforceNetworkFactoryOrSettingsPermission, but offerNetwork enforced no caller permission, although the ConnectivityManager API annotations require NETWORK_FACTORY or MAINLINE_NETWORK_STACK. Per the commit message, an unauthorized app could register a network offer under an existing provider ID (trivially guessed) and intercept all NetworkRequests. This leaked information about other apps (bulletin type ID, severity High).
How the fix works
- service/src/com/android/server/ConnectivityService.java:offerNetwork: after the Objects.requireNonNull checks and before the NetworkOffer is built, the fix branches on caps.hasTransport(TRANSPORT_TEST).
- If the offered capabilities include TRANSPORT_TEST, the fix calls enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS). The commit message says this is consistent with similar APIs in the class.
- Otherwise the fix calls enforceNetworkFactoryPermission(). Per the commit message, this requires NETWORK_FACTORY or MAINLINE_NETWORK_STACK, matching the ConnectivityManager annotations.
- The enforce calls run before EVENT_REGISTER_NETWORK_OFFER is posted to mHandler, so a caller that fails the check does not get an offer queued.
Completeness
- Covers the unguarded binder entry point offerNetwork. The check runs before the offer is posted to mHandler.
- The check covers only the caller's permission. At this entry point, providerId is still not validated against a provider registered by the caller, but the permission check now limits offerNetwork to privileged callers.
- unofferNetwork(callback) still has no permission check. The commit message says this is consistent with the ConnectivityManager API annotations. The function acts only on the callback the caller supplies.
- TRANSPORT_TEST offers are gated by MANAGE_TEST_NETWORKS rather than the factory permission. Because caps.hasTransport(TRANSPORT_TEST) is checked first, an offer whose capabilities include TRANSPORT_TEST takes the test branch even if it also lists other transports.
Behavior changes
- offerNetwork now rejects callers that lack NETWORK_FACTORY or MAINLINE_NETWORK_STACK (non-test offers) or MANAGE_TEST_NETWORKS (offers with TRANSPORT_TEST). The material does not show the exact exception thrown.
- registerNetworkProvider accepts callers that pass enforceNetworkFactoryOrSettingsPermission, but offerNetwork now requires enforceNetworkFactoryPermission (or the test permission). A provider allowed to register only through the settings side of that check may now be refused at offerNetwork.
Per major
- Android 14: same fix: commit 0eccf35b6b1b in android-security-14.0.0_r21 (cherry-pick of ff65257bd07c), using enforceAnyPermissionOf(mContext, ...). All 6/6 lines of the patched region are present at android-security-14.0.0_r29.
- Android 15: same fix: commit a2d3f541c78e in android-security-15.0.0_r9. The hunk is identical apart from the line offset. All 6/6 lines are present at android-security-15.0.0_r17.
- Android 16: adapted fix: commit f27bca2d7d23 in android-16.0.0_r2 (base). It calls enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS) without the mContext argument. All 6/6 lines are present at android-security-16.0.0_r8.
- Android 17: not affected (not listed by the bulletin). The patched region is fully present (6/6 lines) at android-security-17.0.0_r1.
Unknowns
- The diff does not show the exact permission set checked by enforceNetworkFactoryPermission and enforceAnyPermissionOf, or the exception they throw. The NETWORK_FACTORY / MAINLINE_NETWORK_STACK description comes from the commit message.
- The bulletin lists Android 13 as affected, but the material contains no Android 13 commit, so it does not show whether 13 received the fix.
- The commit says 'Test: TH'. The shown diff contains no test changes.