This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 015508e65c Fix various issues
015508e65c is described below
commit 015508e65cc1fd28fd7cf2a878113db7edf8acab
Author: remm <[email protected]>
AuthorDate: Thu May 28 16:13:52 2026 +0200
Fix various issues
Of note an unintended double connection in proxy error report valve.
---
.../valves/CrawlerSessionManagerValve.java | 4 +-
.../catalina/valves/JsonErrorReportValve.java | 4 +-
.../apache/catalina/valves/LocalStrings.properties | 1 +
.../apache/catalina/valves/PersistentValve.java | 6 +-
.../catalina/valves/ProxyErrorReportValve.java | 2 +-
java/org/apache/catalina/valves/SSLValve.java | 6 +-
.../catalina/valves/rewrite/ResolverImpl.java | 151 +++++++++++----------
.../org/apache/coyote/ajp/AbstractAjpProtocol.java | 2 +-
webapps/docs/changelog.xml | 3 +
9 files changed, 97 insertions(+), 82 deletions(-)
diff --git a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java
b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java
index 30c69003da..bfa8859a6b 100644
--- a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java
+++ b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java
@@ -208,7 +208,7 @@ public class CrawlerSessionManagerValve extends ValveBase {
protected void initInternal() throws LifecycleException {
super.initInternal();
- uaPattern = Pattern.compile(crawlerUserAgents);
+ setCrawlerUserAgents(crawlerUserAgents);
}
@@ -249,7 +249,7 @@ public class CrawlerSessionManagerValve extends ValveBase {
log.trace(request.hashCode() + ": UserAgent=" + uaHeader);
}
- if (uaPattern.matcher(uaHeader).matches()) {
+ if (uaPattern != null &&
uaPattern.matcher(uaHeader).matches()) {
isBot = true;
if (log.isTraceEnabled()) {
diff --git a/java/org/apache/catalina/valves/JsonErrorReportValve.java
b/java/org/apache/catalina/valves/JsonErrorReportValve.java
index c71282dab4..9838b8e2ae 100644
--- a/java/org/apache/catalina/valves/JsonErrorReportValve.java
+++ b/java/org/apache/catalina/valves/JsonErrorReportValve.java
@@ -95,6 +95,7 @@ public class JsonErrorReportValve extends ErrorReportValve {
// Stack trace
sb.append(" \"throwable\": [");
+ int loops = 0;
boolean first = true;
do {
if (!first) {
@@ -121,7 +122,8 @@ public class JsonErrorReportValve extends ErrorReportValve {
}
throwable = throwable.getCause();
- } while (throwable != null);
+ loops++;
+ } while (throwable != null && (loops < 10));
sb.append("]\n}");
} else {
diff --git a/java/org/apache/catalina/valves/LocalStrings.properties
b/java/org/apache/catalina/valves/LocalStrings.properties
index 8e486bb94d..80633b8cb1 100644
--- a/java/org/apache/catalina/valves/LocalStrings.properties
+++ b/java/org/apache/catalina/valves/LocalStrings.properties
@@ -173,6 +173,7 @@ requestFilterValve.configInvalid=One or more invalid
configuration settings were
requestFilterValve.deny=Denied request for [{0}] based on property [{1}]
sslValve.certError=Failed to process certificate string [{0}] to create a
java.security.cert.X509Certificate object
+sslValve.invalidHeader=Invalid value [{0}] for header [{1}]
sslValve.invalidProvider=The SSL provider specified on the connector
associated with this request of [{0}] is invalid. The certificate data could
not be processed.
stuckThreadDetectionValve.interrupted=Thread interrupted after the request is
finished, ignoring
diff --git a/java/org/apache/catalina/valves/PersistentValve.java
b/java/org/apache/catalina/valves/PersistentValve.java
index f4f877285a..9f9cbc947c 100644
--- a/java/org/apache/catalina/valves/PersistentValve.java
+++ b/java/org/apache/catalina/valves/PersistentValve.java
@@ -37,6 +37,8 @@ import org.apache.catalina.Store;
import org.apache.catalina.StoreManager;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
/**
* Valve that implements per-request session persistence. It is intended to be
used with non-sticky load-balancers and a
@@ -67,6 +69,8 @@ import org.apache.catalina.connector.Response;
*/
public class PersistentValve extends ValveBase {
+ private static final Log log = LogFactory.getLog(PersistentValve.class);
+
// Saves a couple of calls to getClassLoader() on every request. Under high
// load these calls took just long enough to appear as a hot spot (although
// a very minor one) in a profiler.
@@ -347,7 +351,7 @@ public class PersistentValve extends ValveBase {
try {
this.filter = Pattern.compile(filter);
} catch (PatternSyntaxException pse) {
-
container.getLogger().error(sm.getString("persistentValve.filter.failure",
filter), pse);
+ log.error(sm.getString("persistentValve.filter.failure",
filter), pse);
}
}
}
diff --git a/java/org/apache/catalina/valves/ProxyErrorReportValve.java
b/java/org/apache/catalina/valves/ProxyErrorReportValve.java
index 67e1b373c5..dd5f22e219 100644
--- a/java/org/apache/catalina/valves/ProxyErrorReportValve.java
+++ b/java/org/apache/catalina/valves/ProxyErrorReportValve.java
@@ -230,7 +230,7 @@ public class ProxyErrorReportValve extends ErrorReportValve
{
response.setContentType(httpURLConnection.getContentType());
response.setContentLength(httpURLConnection.getContentLength());
OutputStream outputStream = response.getOutputStream();
- InputStream inputStream = url.openStream();
+ InputStream inputStream = httpURLConnection.getInputStream();
IOTools.flow(inputStream, outputStream);
} catch (URISyntaxException | IOException |
IllegalArgumentException e) {
if (log.isDebugEnabled()) {
diff --git a/java/org/apache/catalina/valves/SSLValve.java
b/java/org/apache/catalina/valves/SSLValve.java
index 6f075d21c4..c6ae6e6e8e 100644
--- a/java/org/apache/catalina/valves/SSLValve.java
+++ b/java/org/apache/catalina/valves/SSLValve.java
@@ -272,7 +272,11 @@ public class SSLValve extends ValveBase {
}
headerValue = mygetHeader(request, sslCipherUserKeySizeHeader);
if (headerValue != null) {
- request.setAttribute(Globals.KEY_SIZE_ATTR,
Integer.valueOf(headerValue));
+ try {
+ request.setAttribute(Globals.KEY_SIZE_ATTR,
Integer.valueOf(headerValue));
+ } catch (NumberFormatException e) {
+ log.warn(sm.getString("sslValve.invalidHeader", headerValue,
sslCipherUserKeySizeHeader));
+ }
}
getNext().invoke(request, response);
}
diff --git a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
index 47e19fe171..7b5968c14a 100644
--- a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
+++ b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
@@ -152,87 +152,88 @@ public class ResolverImpl extends Resolver {
@Override
public String resolveSsl(String key) {
- SSLSupport sslSupport = (SSLSupport)
request.getAttribute(SSLSupport.SESSION_MGR);
- try {
- // SSL_SRP_USER: no planned support for SRP
- // SSL_SRP_USERINFO: no planned support for SRP
- if (key.equals("HTTPS")) {
- return String.valueOf(sslSupport != null);
- } else if (key.equals("SSL_PROTOCOL")) {
- return sslSupport.getProtocol();
- } else if (key.equals("SSL_SESSION_ID")) {
- return sslSupport.getSessionId();
- } else if (key.equals("SSL_SESSION_RESUMED")) {
- // FIXME session resumption state, not available anywhere
- } else if (key.equals("SSL_SECURE_RENEG")) {
- // FIXME available from SSLHostConfig
- } else if (key.equals("SSL_COMPRESS_METHOD")) {
- // FIXME available from SSLHostConfig
- } else if (key.equals("SSL_TLS_SNI")) {
- // FIXME from handshake SNI processing
- } else if (key.equals("SSL_CIPHER")) {
- return sslSupport.getCipherSuite();
- } else if (key.equals("SSL_CIPHER_EXPORT")) {
- String cipherSuite = sslSupport.getCipherSuite();
- if (cipherSuite != null) {
- Set<Cipher> cipherList =
OpenSSLCipherConfigurationParser.parse(cipherSuite);
- if (cipherList.size() == 1) {
- Cipher cipher = cipherList.iterator().next();
- if (cipher.getLevel().equals(EncryptionLevel.EXP40) ||
-
cipher.getLevel().equals(EncryptionLevel.EXP56)) {
- return "true";
- } else {
- return "false";
+ if (request.getAttribute(SSLSupport.SESSION_MGR) instanceof SSLSupport
sslSupport) {
+ try {
+ // SSL_SRP_USER: no planned support for SRP
+ // SSL_SRP_USERINFO: no planned support for SRP
+ if (key.equals("HTTPS")) {
+ return String.valueOf(sslSupport != null);
+ } else if (key.equals("SSL_PROTOCOL")) {
+ return sslSupport.getProtocol();
+ } else if (key.equals("SSL_SESSION_ID")) {
+ return sslSupport.getSessionId();
+ } else if (key.equals("SSL_SESSION_RESUMED")) {
+ // FIXME session resumption state, not available anywhere
+ } else if (key.equals("SSL_SECURE_RENEG")) {
+ // FIXME available from SSLHostConfig
+ } else if (key.equals("SSL_COMPRESS_METHOD")) {
+ // FIXME available from SSLHostConfig
+ } else if (key.equals("SSL_TLS_SNI")) {
+ // FIXME from handshake SNI processing
+ } else if (key.equals("SSL_CIPHER")) {
+ return sslSupport.getCipherSuite();
+ } else if (key.equals("SSL_CIPHER_EXPORT")) {
+ String cipherSuite = sslSupport.getCipherSuite();
+ if (cipherSuite != null) {
+ Set<Cipher> cipherList =
OpenSSLCipherConfigurationParser.parse(cipherSuite);
+ if (cipherList.size() == 1) {
+ Cipher cipher = cipherList.iterator().next();
+ if
(cipher.getLevel().equals(EncryptionLevel.EXP40) ||
+
cipher.getLevel().equals(EncryptionLevel.EXP56)) {
+ return "true";
+ } else {
+ return "false";
+ }
}
}
- }
- } else if (key.equals("SSL_CIPHER_ALGKEYSIZE")) {
- String cipherSuite = sslSupport.getCipherSuite();
- if (cipherSuite != null) {
- Set<Cipher> cipherList =
OpenSSLCipherConfigurationParser.parse(cipherSuite);
- if (cipherList.size() == 1) {
- Cipher cipher = cipherList.iterator().next();
- return String.valueOf(cipher.getAlg_bits());
+ } else if (key.equals("SSL_CIPHER_ALGKEYSIZE")) {
+ String cipherSuite = sslSupport.getCipherSuite();
+ if (cipherSuite != null) {
+ Set<Cipher> cipherList =
OpenSSLCipherConfigurationParser.parse(cipherSuite);
+ if (cipherList.size() == 1) {
+ Cipher cipher = cipherList.iterator().next();
+ return String.valueOf(cipher.getAlg_bits());
+ }
}
- }
- } else if (key.equals("SSL_CIPHER_USEKEYSIZE")) {
- Integer keySize = sslSupport.getKeySize();
- return (keySize == null) ? null :
sslSupport.getKeySize().toString();
- } else if (key.startsWith("SSL_CLIENT_")) {
- X509Certificate[] certificates =
sslSupport.getPeerCertificateChain();
- if (certificates != null && certificates.length > 0) {
- key = key.substring("SSL_CLIENT_".length());
- String result = resolveSslCertificates(key, certificates);
- if (result != null) {
- return result;
- } else if (key.startsWith("SAN_OTHER_msUPN_")) {
- // Type otherName, which is 0
- key = key.substring("SAN_OTHER_msUPN_".length());
- // FIXME OID from resolveAlternateName
- } else if (key.equals("CERT_RFC4523_CEA")) {
- // FIXME return certificate[0] format
CertificateExactAssertion in RFC4523
- } else if (key.equals("VERIFY")) {
- // FIXME return verification state, not available
anywhere
+ } else if (key.equals("SSL_CIPHER_USEKEYSIZE")) {
+ Integer keySize = sslSupport.getKeySize();
+ return (keySize == null) ? null :
sslSupport.getKeySize().toString();
+ } else if (key.startsWith("SSL_CLIENT_")) {
+ X509Certificate[] certificates =
sslSupport.getPeerCertificateChain();
+ if (certificates != null && certificates.length > 0) {
+ key = key.substring("SSL_CLIENT_".length());
+ String result = resolveSslCertificates(key,
certificates);
+ if (result != null) {
+ return result;
+ } else if (key.startsWith("SAN_OTHER_msUPN_")) {
+ // Type otherName, which is 0
+ key = key.substring("SAN_OTHER_msUPN_".length());
+ // FIXME OID from resolveAlternateName
+ } else if (key.equals("CERT_RFC4523_CEA")) {
+ // FIXME return certificate[0] format
CertificateExactAssertion in RFC4523
+ } else if (key.equals("VERIFY")) {
+ // FIXME return verification state, not available
anywhere
+ }
}
- }
- } else if (key.startsWith("SSL_SERVER_")) {
- X509Certificate[] certificates =
sslSupport.getLocalCertificateChain();
- if (certificates != null && certificates.length > 0) {
- key = key.substring("SSL_SERVER_".length());
- String result = resolveSslCertificates(key, certificates);
- if (result != null) {
- return result;
- } else if (key.startsWith("SAN_OTHER_dnsSRV_")) {
- // Type otherName, which is 0
- key = key.substring("SAN_OTHER_dnsSRV_".length());
- // FIXME OID from resolveAlternateName
+ } else if (key.startsWith("SSL_SERVER_")) {
+ X509Certificate[] certificates =
sslSupport.getLocalCertificateChain();
+ if (certificates != null && certificates.length > 0) {
+ key = key.substring("SSL_SERVER_".length());
+ String result = resolveSslCertificates(key,
certificates);
+ if (result != null) {
+ return result;
+ } else if (key.startsWith("SAN_OTHER_dnsSRV_")) {
+ // Type otherName, which is 0
+ key = key.substring("SAN_OTHER_dnsSRV_".length());
+ // FIXME OID from resolveAlternateName
+ }
}
}
- }
- } catch (IOException ioe) {
- // TLS access error
- if (containerLog.isDebugEnabled()) {
- containerLog.debug(sm.getString("resolverImpl.tlsError"), ioe);
+ } catch (IOException ioe) {
+ // TLS access error
+ if (containerLog.isDebugEnabled()) {
+ containerLog.debug(sm.getString("resolverImpl.tlsError"),
ioe);
+ }
}
}
return null;
diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
index 3354eeebfa..7fb306f416 100644
--- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
+++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
@@ -223,7 +223,7 @@ public abstract class AbstractAjpProtocol<S> extends
AbstractProtocol<S> {
* @return the pattern string
*/
public String getAllowedRequestAttributesPattern() {
- return allowedRequestAttributesPattern.pattern();
+ return allowedRequestAttributesPattern != null ?
allowedRequestAttributesPattern.pattern() : null;
}
/**
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ab987670bb..0f9085fb33 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -215,6 +215,9 @@
than a <code>500</code> response. Pull request <pr>1012</pr> provided
by
Sahana Surendra Bogar. (markt)
</fix>
+ <fix>
+ Fix connection leak in <code>ProxyErrorReportValve</code>. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]