OOM on Android 8/9 when getting "https://icloud.com"
See original GitHub issueHello,
When trying to GET
(or PROPFIND
) https://icloud.com (without www) with code like that:
// compileSdkVersion 27
// buildToolsVersion '28.0.1'
// targetSdkVersion 27
// Kotlin 1.2.51
class ClientTest {
@Test
fun testIcloud() {
val client = OkHttpClient()
client.newCall(Request.Builder()
.get()
.url("https://icloud.com")
.build())
.execute()
}
}
it takes a long time until the process is killed with OOM and the test fails:
Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (light greylist, reflection)
Background concurrent copying GC freed 12119(2MB) AllocSpace objects, 2(40KB) LOS objects, 53% free, 1347KB/2MB, paused 5.288ms total 13.790ms
Background concurrent copying GC freed 255556(7MB) AllocSpace objects, 0(0B) LOS objects, 3% free, 153MB/159MB, paused 160us total 1.134s
Waiting for a blocking GC Alloc
Background concurrent copying GC freed 1659257(48MB) AllocSpace objects, 0(0B) LOS objects, 4% free, 143MB/149MB, paused 166us total 751.739ms
WaitForGcToComplete blocked Alloc on ProfileSaver for 84.800ms
Starting a blocking GC Alloc
Waiting for a blocking GC Alloc
NativeAlloc concurrent copying GC freed 613455(17MB) AllocSpace objects, 0(0B) LOS objects, 3% free, 171MB/177MB, paused 715us total 800.326ms
WaitForGcToComplete blocked Alloc on HeapTrim for 78.698ms
Starting a blocking GC Alloc
Starting a blocking GC Alloc
Starting a blocking GC Alloc
Alloc concurrent copying GC freed 1471248(40MB) AllocSpace objects, 11(26MB) LOS objects, 4% free, 120MB/126MB, paused 617us total 440.035ms
Waiting for a blocking GC Alloc
Background concurrent copying GC freed 212754(4MB) AllocSpace objects, 1(4MB) LOS objects, 3% free, 179MB/185MB, paused 1.906ms total 414.292ms
WaitForGcToComplete blocked Alloc on HeapTrim for 378.426ms
Starting a blocking GC Alloc
Waiting for a blocking GC Alloc
Background concurrent copying GC freed 116(286KB) AllocSpace objects, 14(45MB) LOS objects, 3% free, 146MB/152MB, paused 759us total 705.920ms
WaitForGcToComplete blocked Alloc on HeapTrim for 631.676ms
Starting a blocking GC Alloc
Waiting for a blocking GC Alloc
…
Starting a blocking GC Alloc
Throwing OutOfMemoryError "Failed to allocate a 32 byte allocation with 16 free bytes and 16B until OOM, max allowed footprint 201326592, growth limit 201326592" (recursive case)
"Instr: android.support.test.runner.AndroidJUnitRunner" prio=5 tid=13 Runnable
| group="main" sCount=0 dsCount=0 flags=2 obj=0x12c40a80 self=0x7377c9337400
| sysTid=9630 nice=-8 cgrp=default sched=0/0 handle=0x7377b11934f0
| state=R schedstat=( 17608058590 1326008400 7326 ) utm=1681 stm=79 core=1 HZ=100
| stack=0x7377b1090000-0x7377b1092000 stackSize=1041KB
| held mutexes= "mutator lock"(shared held)
at libcore.util.NativeAllocationRegistry.registerNativeAllocation(NativeAllocationRegistry.java:129)
at java.math.BigInt.makeValid(BigInt.java:48)
at java.math.BigInt.putBigEndianTwosComplement(BigInt.java:179)
at java.math.BigInteger.<init>(BigInteger.java:304)
at sun.security.util.DerInputBuffer.getBigInteger(DerInputBuffer.java:170)
at sun.security.util.DerValue.getBigInteger(DerValue.java:529)
at sun.security.x509.SerialNumber.construct(SerialNumber.java:44)
at sun.security.x509.SerialNumber.<init>(SerialNumber.java:86)
at sun.security.x509.X509CRLEntryImpl.parse(X509CRLEntryImpl.java:460)
at sun.security.x509.X509CRLEntryImpl.<init>(X509CRLEntryImpl.java:133)
at sun.security.x509.X509CRLImpl.parse(X509CRLImpl.java:1161)
at sun.security.x509.X509CRLImpl.<init>(X509CRLImpl.java:146)
at sun.security.provider.X509Factory.intern(X509Factory.java:206)
at sun.security.x509.X509CRLImpl.toImpl(X509CRLImpl.java:1235)
at sun.security.provider.certpath.AlgorithmChecker.check(AlgorithmChecker.java:396)
at sun.security.provider.certpath.DistributionPointFetcher.verifyCRL(DistributionPointFetcher.java:667)
at sun.security.provider.certpath.DistributionPointFetcher.getCRLs(DistributionPointFetcher.java:209)
at sun.security.provider.certpath.DistributionPointFetcher.getCRLs(DistributionPointFetcher.java:121)
at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:552)
at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:465)
at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:394)
at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:337)
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:222)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:301)
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:703)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:539)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:560)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:605)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:495)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:418)
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:339)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:208)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:404)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:375)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:224)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:318)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:282)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:167)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall.execute(RealCall.java:77)
at at.bitfire.davdroid.ClientTest.testIcloud(ClientTest.kt:24)
at java.lang.reflect.Method.invoke(Native method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2145)
Waiting for a blocking GC Alloc
Clamp target GC heap from 198MB to 192MB
Alloc concurrent copying GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 0% free, 192MB/192MB, paused 179us total 576.416ms
Starting a blocking GC Alloc
Waiting for a blocking GC Alloc
Alloc concurrent copying GC freed 4321630(114MB) AllocSpace objects, 7(51MB) LOS objects, 19% free, 25MB/31MB, paused 147us total 245.441ms
WaitForGcToComplete blocked Alloc on HeapTrim for 807.852ms
Starting a blocking GC Alloc
07-16 14:23:09.335 9513-9630/at.bitfire.cloudsync I/TestRunner: failed: testIcloud(at.bitfire.davdroid.ClientTest)
----- begin exception -----
java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
----- end exception -----
07-16 14:23:09.336 9513-9630/at.bitfire.cloudsync I/TestRunner: finished: testIcloud(at.bitfire.davdroid.ClientTest)
07-16 14:23:09.339 9513-9513/at.bitfire.cloudsync I/MonitoringInstr: Activities that are still in CREATED to STOPPED: 0
07-16 14:23:09.340 9513-9630/at.bitfire.cloudsync I/TestRunner: run finished: 1 tests, 1 failed, 0 ignored
07-16 14:23:09.494 9513-9630/at.bitfire.cloudsync I/MonitoringInstr: waitForActivitiesToComplete() took: 1ms
07-16 14:23:09.494 9513-9513/at.bitfire.cloudsync I/MonitoringInstr: Activities that are still in CREATED to STOPPED: 0
This happens with Android 8.0 and 9.0 (emulator from SDK), but not with Android 4.4 (haven’t tested other versions yet).
The problem occurs with okhttp 3.10.0 and 3.11.0 (haven’t tested other versions yet).
Everything is working for some other URLs I have tested, including www.icloud.com. It seems to be related to parsing the certificate. When using a custom trust manager (from https://gitlab.com/bitfireAT/cert4android), it works.
I don’t know whether this is an okhttp problem (looks like an Android problem?), but I guess it’s quite important to understand why a simple GET
request causes the whole process to crash.
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (5 by maintainers)
Top GitHub Comments
I have to apologize. Maybe I got the cert from openssl when debugging and took the wrong one. You would have to see what cert okhttp uses directly.
Interesting bug. Please also report to the conscrypt tracker.
https://github.com/google/conscrypt/issues