8168069: X509TrustManagerImpl causes ClassLoader leaks with unparseable extensions

Reviewed-by: mullan
This commit is contained in:
Xue-Lei Andrew Fan 2019-02-20 18:46:30 -08:00
parent e2054e3c5d
commit e6f6863cbc
4 changed files with 56 additions and 36 deletions

View file

@ -921,29 +921,45 @@ public abstract class SSLContextImpl extends SSLContextSpi {
static {
Exception reserved = null;
TrustManager[] tmMediator;
TrustManager[] tmMediator = null;
try {
tmMediator = getTrustManagers();
} catch (Exception e) {
reserved = e;
tmMediator = new TrustManager[0];
if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
SSLLogger.warning(
"Failed to load default trust managers", e);
}
}
trustManagers = tmMediator;
KeyManager[] kmMediator = null;
if (reserved == null) {
KeyManager[] kmMediator;
try {
kmMediator = getKeyManagers();
} catch (Exception e) {
reserved = e;
kmMediator = new KeyManager[0];
if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
SSLLogger.warning(
"Failed to load default key managers", e);
}
}
keyManagers = kmMediator;
} else {
keyManagers = new KeyManager[0];
}
reservedException = reserved;
if (reserved != null) {
trustManagers = new TrustManager[0];
keyManagers = new KeyManager[0];
// Important note: please don't reserve the original exception
// object, which may be not garbage collection friendly as
// 'reservedException' is a static filed.
reservedException =
new KeyManagementException(reserved.getMessage());
} else {
trustManagers = tmMediator;
keyManagers = kmMediator;
reservedException = null;
}
}
private static TrustManager[] getTrustManagers() throws Exception {
@ -1071,21 +1087,30 @@ public abstract class SSLContextImpl extends SSLContextSpi {
private static final class DefaultSSLContextHolder {
private static final SSLContextImpl sslContext;
static Exception reservedException = null;
private static final Exception reservedException;
static {
Exception reserved = null;
SSLContextImpl mediator = null;
if (DefaultManagersHolder.reservedException != null) {
reservedException = DefaultManagersHolder.reservedException;
reserved = DefaultManagersHolder.reservedException;
} else {
try {
mediator = new DefaultSSLContext();
} catch (Exception e) {
reservedException = e;
// Important note: please don't reserve the original
// exception object, which may be not garbage collection
// friendly as 'reservedException' is a static filed.
reserved = new KeyManagementException(e.getMessage());
if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
SSLLogger.warning(
"Failed to load default SSLContext", e);
}
}
}
sslContext = mediator;
reservedException = reserved;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -355,7 +355,7 @@ public class CertificateExtensions implements CertAttrSet<Extension> {
class UnparseableExtension extends Extension {
private String name;
private Throwable why;
private String exceptionDescription;
public UnparseableExtension(Extension ext, Throwable why) {
super(ext);
@ -371,12 +371,13 @@ class UnparseableExtension extends Extension {
// If we cannot find the name, just ignore it
}
this.why = why;
this.exceptionDescription = why.toString();
}
@Override public String toString() {
return super.toString() +
"Unparseable " + name + "extension due to\n" + why + "\n\n" +
"Unparseable " + name + "extension due to\n" +
exceptionDescription + "\n\n" +
new HexDumpEncoder().encodeBuffer(getExtensionValue());
}
}