From 5be04946ab6339d0a87d56aa2e9a85737b915b8e Mon Sep 17 00:00:00 2001 From: ChoiSeungMyung <41726791+ChoiSeungMyung@users.noreply.github.com> Date: Wed, 26 Aug 2026 16:31:54 +0900 Subject: [PATCH] android: advance the alias counter before continuing in isKnownRoot `isKnownRoot` walks the collision-suffixed aliases of a system trust anchor. `i += 1` was the last statement of the loop body, and two of the three branches reach the next iteration via `continue`, jumping over it. When either is taken the alias is recomputed to the same string, the same file still exists so the loop does not break, and the keystore returns the same value, so the branch is taken again forever. The thread running the handshake never returns and keeps a core busy repeating one `File.exists()` and one `getCertificate()`. The `anchor == null` branch is reachable exactly as its own comment describes. conscrypt's TrustedCertificateStore returns null for a system alias once the certificate has been copied into $ANDROID_DATA/misc/keychain/cacerts-removed, which is what happens when a user disables a preinstalled CA; the file under $ANDROID_ROOT/etc/security/cacerts stays on disk because that partition is read-only. The Chromium code this was ported from keeps the increment in the update clause of a C-style `for`, so `continue` still advances there. Kotlin has no such form and the port moved it into the body, which changed what `continue` does. Incrementing right after the alias is built restores that invariant: progress no longer depends on how many `continue` paths the body has. `i` is not read after the loop, so incrementing before the `break` check is harmless. Fixes #245 --- .../java/org/rustls/platformverifier/CertificateVerifier.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/android/rustls-platform-verifier/src/main/java/org/rustls/platformverifier/CertificateVerifier.kt b/android/rustls-platform-verifier/src/main/java/org/rustls/platformverifier/CertificateVerifier.kt index febbcfd2..b9358aa4 100644 --- a/android/rustls-platform-verifier/src/main/java/org/rustls/platformverifier/CertificateVerifier.kt +++ b/android/rustls-platform-verifier/src/main/java/org/rustls/platformverifier/CertificateVerifier.kt @@ -431,6 +431,7 @@ internal object CertificateVerifier { var i = 0 while (true) { val alias = "$hash.$i" + i += 1 if (!File(loadedSystemCertificateDirectory, alias).exists()) { break @@ -457,8 +458,6 @@ internal object CertificateVerifier { return true } } - - i += 1 } } }