CVE-2026-0073 AI-generated analysis
platform/packages/modules/adb, adbd daemon TLS authentication (daemon/auth.cpp)
In adbd's TLS client-certificate verification (daemon/auth.cpp, adbd_tls_verify_cert), the EVP_PKEY_cmp result now counts as a key match only when it is exactly 1, not for any non-zero value. Error and non-comparable return codes are no longer treated as a match.
Root cause
adbd_tls_verify_cert goes through the stored authorized public keys (IteratePublicKeys). It decodes each one into an RSA key wrapped in an EVP_PKEY (known_evp) and compares it with EVP_PKEY_cmp against the public key taken from the peer's X509 certificate (evp_pkey). The original code used `if (EVP_PKEY_cmp(...))`, so every non-zero return counted as a match. The commit message says "Not all non-zero values mean success". In BoringSSL/OpenSSL, EVP_PKEY_cmp returns 1 for a match and negative values when the keys cannot be compared, for example because the key types differ (general platform knowledge). With the truthiness test, any non-zero non-1 result set verified = true, set *auth_key to the stored key and made the function return 1 (authorized). A certificate whose key did not actually match a stored key could therefore be accepted by this check.
How the fix works
- daemon/auth.cpp:adbd_tls_verify_cert: the return value of EVP_PKEY_cmp(known_evp.get(), evp_pkey.get()) is stored in `int cmp_result`, and the match branch is taken only when `cmp_result == 1`. Every other value goes to the non-match branch, which leaves verified = false and authorized unchanged.
- daemon/auth.cpp:adbd_tls_verify_cert: the non-match log line now appends `EVP_PKEY_cmp returned <cmp_result>`. No other logic changed.
Completeness
- The fix covers the single EVP_PKEY_cmp call in adbd_tls_verify_cert, which is the only key comparison shown in the material. The surrounding loop, the base64 and decode error paths and the final `return authorized ? 1 : 0` are unchanged.
- The return value of EVP_PKEY_set1_RSA(known_evp.get(), key) in the same block is still unchecked. With the fix, any EVP_PKEY_cmp result other than 1 is treated as a non-match.
- The diff includes no test. The commit points to a test in b/469080888#comment6, which is not provided.
Behavior changes
- Stricter acceptance: adbd_tls_verify_cert now authorizes the peer certificate only when EVP_PKEY_cmp returns exactly 1. Any other result is treated as a mismatch, and if no stored key matches, the function returns 0.
- The log message on mismatch now includes the numeric EVP_PKEY_cmp return value (LOG(INFO) on 14 and 15, VLOG(AUTH) on 16).
Per major
- Android 14: same fix: commit 4492fa1affa1 in android-security-14.0.0_r27 (LOG(INFO) variant). At android-security-14.0.0_r29, 5 of 7 lines of the patched region are present, and the code shown contains the cmp_result == 1 check.
- Android 15: same fix: commit 7cd495a9b4b7 in android-security-15.0.0_r15, with a diff identical to 14. At android-security-15.0.0_r17, 5 of 7 lines of the patched region are present.
- Android 16: adapted fix: commit 842d331f9e5f in android-security-16.0.0_r6. The logic change is the same, but the log statements use VLOG(AUTH) instead of LOG(INFO). At android-security-16.0.0_r8, 5 of 7 lines of the patched region are present.
- Android 17: not affected per the bulletin (not listed). The per-major facts show 4 of 7 lines of the patched region at android-security-17.0.0_r1, and the material does not explain this further.
Unknowns
- Which EVP_PKEY_cmp return values can occur in practice with the BoringSSL version in each branch.
- How adbd_tls_verify_cert is registered as the verification callback for the TLS server connection (the index snippet does not show it).
- Why Android 17 is not listed, and what its code at android-security-17.0.0_r1 looks like (only a 4/7 line match is reported).
- The content of the referenced test (b/469080888#comment6).