From 90ce6a11fcfa3e87e0521c71f3390a971aa4f6a2 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 29 2020 07:03:55 +0000 Subject: import tomcat-7.0.76-15.el7 --- diff --git a/SOURCES/tomcat-7.0.76-CVE-2019-17563.patch b/SOURCES/tomcat-7.0.76-CVE-2019-17563.patch new file mode 100644 index 0000000..3b493de --- /dev/null +++ b/SOURCES/tomcat-7.0.76-CVE-2019-17563.patch @@ -0,0 +1,120 @@ +diff -up ./java/org/apache/catalina/authenticator/AuthenticatorBase.java.orig ./java/org/apache/catalina/authenticator/AuthenticatorBase.java +--- ./java/org/apache/catalina/authenticator/AuthenticatorBase.java.orig 2020-04-24 11:29:17.047848947 -0400 ++++ ./java/org/apache/catalina/authenticator/AuthenticatorBase.java 2020-04-24 11:36:59.943955494 -0400 +@@ -854,10 +854,11 @@ public abstract class AuthenticatorBase + } + + // Cache the authentication information in our session, if any +- if (cache) { +- if (session != null) { ++ if (session != null) { ++ if (cache) { + session.setAuthType(authType); + session.setPrincipal(principal); ++ } else { + if (username != null) + session.setNote(Constants.SESS_USERNAME_NOTE, username); + else +diff -up ./java/org/apache/catalina/authenticator/Constants.java.orig ./java/org/apache/catalina/authenticator/Constants.java +--- ./java/org/apache/catalina/authenticator/Constants.java.orig 2020-04-24 11:29:23.513836466 -0400 ++++ ./java/org/apache/catalina/authenticator/Constants.java 2020-04-24 11:37:43.381871646 -0400 +@@ -119,7 +119,10 @@ public class Constants { + + /** + * The previously authenticated principal (if caching is disabled). ++ * ++ * @deprecated Unused. Will be removed in Tomcat 10. + */ ++ @Deprecated + public static final String FORM_PRINCIPAL_NOTE = + "org.apache.catalina.authenticator.PRINCIPAL"; + +diff -up ./java/org/apache/catalina/authenticator/FormAuthenticator.java.orig ./java/org/apache/catalina/authenticator/FormAuthenticator.java +--- ./java/org/apache/catalina/authenticator/FormAuthenticator.java.orig 2020-04-24 11:29:30.865822275 -0400 ++++ ./java/org/apache/catalina/authenticator/FormAuthenticator.java 2020-04-24 11:41:51.489392742 -0400 +@@ -149,10 +149,6 @@ public class FormAuthenticator + LoginConfig config) + throws IOException { + +- if (checkForCachedAuthentication(request, response, true)) { +- return (true); +- } +- + // References to objects we will need later + Session session = null; + Principal principal = null; +@@ -174,11 +170,8 @@ public class FormAuthenticator + principal = + context.getRealm().authenticate(username, password); + if (principal != null) { +- session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal); ++ register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); + if (!matchRequest(request)) { +- register(request, response, principal, +- HttpServletRequest.FORM_AUTH, +- username, password); + return (true); + } + } +@@ -197,17 +190,6 @@ public class FormAuthenticator + + session.getIdInternal() + + "'"); + } +- principal = (Principal) +- session.getNote(Constants.FORM_PRINCIPAL_NOTE); +- register(request, response, principal, HttpServletRequest.FORM_AUTH, +- (String) session.getNote(Constants.SESS_USERNAME_NOTE), +- (String) session.getNote(Constants.SESS_PASSWORD_NOTE)); +- // If we're caching principals we no longer need the username +- // and password in the session, so remove them +- if (cache) { +- session.removeNote(Constants.SESS_USERNAME_NOTE); +- session.removeNote(Constants.SESS_PASSWORD_NOTE); +- } + if (restoreRequest(request, session)) { + if (log.isDebugEnabled()) { + log.debug("Proceed to restored request"); +@@ -222,6 +204,12 @@ public class FormAuthenticator + } + } + ++ // This check has to be after the previous check for a matching request ++ // because that matching request may also include a cached Principal. ++ if (checkForCachedAuthentication(request, response, true)) { ++ return true; ++ } ++ + // Acquire references to objects we will need to evaluate + MessageBytes uriMB = MessageBytes.newInstance(); + CharChunk uriCC = uriMB.getCharChunk(); +@@ -314,12 +302,7 @@ public class FormAuthenticator + return (false); + } + +- // Save the authenticated Principal in our session +- session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal); +- +- // Save the username and password as well +- session.setNote(Constants.SESS_USERNAME_NOTE, username); +- session.setNote(Constants.SESS_PASSWORD_NOTE, password); ++ register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); + + // Redirect the user to the original request URI (which will cause + // the original request to be restored) +@@ -489,7 +472,7 @@ public class FormAuthenticator + } + + // Is there a saved principal? +- if (session.getNote(Constants.FORM_PRINCIPAL_NOTE) == null) { ++ if (cache && session.getPrincipal() == null || !cache && request.getPrincipal() == null) { + return (false); + } + +@@ -518,7 +501,6 @@ public class FormAuthenticator + SavedRequest saved = (SavedRequest) + session.getNote(Constants.FORM_REQUEST_NOTE); + session.removeNote(Constants.FORM_REQUEST_NOTE); +- session.removeNote(Constants.FORM_PRINCIPAL_NOTE); + if (saved == null) { + return (false); + } diff --git a/SOURCES/tomcat-7.0.76-CVE-2020-13935.patch b/SOURCES/tomcat-7.0.76-CVE-2020-13935.patch new file mode 100644 index 0000000..6be4258 --- /dev/null +++ b/SOURCES/tomcat-7.0.76-CVE-2020-13935.patch @@ -0,0 +1,75 @@ +diff -up ./java/org/apache/catalina/websocket/LocalStrings.properties.orig ./java/org/apache/catalina/websocket/LocalStrings.properties +--- ./java/org/apache/catalina/websocket/LocalStrings.properties.orig 2020-07-17 15:26:30.639711576 -0400 ++++ ./java/org/apache/catalina/websocket/LocalStrings.properties 2020-07-17 15:26:39.051723026 -0400 +@@ -14,6 +14,7 @@ + # limitations under the License. + + frame.eos=The end of the stream was reached before the expected number of payload bytes could be read ++frame.invalidLength=An invalid payload length was specified + frame.invalidUtf8=A sequence of bytes was received that did not represent valid UTF-8 + frame.readFailed=Failed to read the first byte of the next WebSocket frame. The return value from the read was [{0}] + frame.readEos=The end of the stream was reached when trying to read the first byte of a new WebSocket frame +diff -up ./java/org/apache/catalina/websocket/WsFrame.java.orig ./java/org/apache/catalina/websocket/WsFrame.java +--- ./java/org/apache/catalina/websocket/WsFrame.java.orig 2020-07-17 15:26:44.341730227 -0400 ++++ ./java/org/apache/catalina/websocket/WsFrame.java 2020-07-17 15:27:02.712755233 -0400 +@@ -84,6 +84,12 @@ public class WsFrame { + blockingRead(processor, extended); + payloadLength = Conversions.byteArrayToLong(extended); + } ++ // The most significant bit of those 8 bytes is required to be zero ++ // (see RFC 6455, section 5.2). If the most significant bit is set, ++ // the resulting payload length will be negative so test for that. ++ if (payloadLength < 0) { ++ throw new IOException(sm.getString("frame.invalidLength")); ++ } + + if (isControl()) { + if (payloadLength > 125) { +diff -up ./java/org/apache/tomcat/websocket/LocalStrings.properties.orig ./java/org/apache/tomcat/websocket/LocalStrings.properties +--- ./java/org/apache/tomcat/websocket/LocalStrings.properties.orig 2020-07-17 15:25:18.940613973 -0400 ++++ ./java/org/apache/tomcat/websocket/LocalStrings.properties 2020-07-17 15:25:24.954622163 -0400 +@@ -63,6 +63,7 @@ wsFrame.noContinuation=A new message was + wsFrame.notMasked=The client frame was not masked but all client frames must be masked + wsFrame.oneByteCloseCode=The client sent a close frame with a single byte payload which is not valid + wsFrame.partialHeaderComplete=WebSocket frame received. fin [{0}], rsv [{1}], OpCode [{2}], payload length [{3}] ++wsFrame.payloadMsbInvalid=An invalid WebSocket frame was received - the most significant bit of a 64-bit payload was illegally set + wsFrame.sessionClosed=The client data cannot be processed because the session has already been closed + wsFrame.textMessageTooBig=The decoded text message was too big for the output buffer and the endpoint does not support partial messages + wsFrame.wrongRsv=The client frame set the reserved bits to [{0}] for a message with opCode [{1}] which was not supported by this endpoint +diff -up ./java/org/apache/tomcat/websocket/WsFrameBase.java.orig ./java/org/apache/tomcat/websocket/WsFrameBase.java +--- ./java/org/apache/tomcat/websocket/WsFrameBase.java.orig 2020-07-17 15:25:04.371594139 -0400 ++++ ./java/org/apache/tomcat/websocket/WsFrameBase.java 2020-07-17 15:25:14.292607645 -0400 +@@ -260,6 +260,13 @@ public abstract class WsFrameBase { + readPos += 2; + } else if (payloadLength == 127) { + payloadLength = byteArrayToLong(inputBuffer, readPos, 8); ++ // The most significant bit of those 8 bytes is required to be zero ++ // (see RFC 6455, section 5.2). If the most significant bit is set, ++ // the resulting payload length will be negative so test for that. ++ if (payloadLength < 0) { ++ throw new WsIOException( ++ new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.payloadMsbInvalid"))); ++ } + readPos += 8; + } + if (Util.isControl(opCode)) { +diff -up ./webapps/docs/changelog.xml.orig ./webapps/docs/changelog.xml +--- ./webapps/docs/changelog.xml.orig 2020-07-20 10:35:46.126504549 -0400 ++++ ./webapps/docs/changelog.xml 2020-07-20 10:36:48.577591763 -0400 +@@ -57,6 +57,16 @@ + They eventually become mixed with the numbered issues. (I.e., numbered + issues do not "pop up" wrt. others). + --> ++
++ ++ ++ ++ 64563: Add additional validation of payload length for ++ WebSocket messages. (markt) ++ ++ ++ ++
+
+ + diff --git a/SOURCES/tomcat-7.0.76-CVE-2020-9484.patch b/SOURCES/tomcat-7.0.76-CVE-2020-9484.patch index fc13d53..0dfcd27 100644 --- a/SOURCES/tomcat-7.0.76-CVE-2020-9484.patch +++ b/SOURCES/tomcat-7.0.76-CVE-2020-9484.patch @@ -1,6 +1,6 @@ diff -up ./java/org/apache/catalina/session/FileStore.java.orig ./java/org/apache/catalina/session/FileStore.java ---- ./java/org/apache/catalina/session/FileStore.java.orig 2017-03-09 08:51:39.000000000 -0500 -+++ ./java/org/apache/catalina/session/FileStore.java 2020-05-21 16:30:46.328792003 -0400 +--- ./java/org/apache/catalina/session/FileStore.java.orig 2020-05-21 16:11:53.278807740 -0400 ++++ ./java/org/apache/catalina/session/FileStore.java 2020-05-21 16:13:55.102531264 -0400 @@ -32,6 +32,8 @@ import org.apache.catalina.Context; import org.apache.catalina.Loader; import org.apache.catalina.Session; @@ -45,8 +45,8 @@ diff -up ./java/org/apache/catalina/session/FileStore.java.orig ./java/org/apach } } diff -up ./java/org/apache/catalina/session/LocalStrings.properties.orig ./java/org/apache/catalina/session/LocalStrings.properties ---- ./java/org/apache/catalina/session/LocalStrings.properties.orig 2017-03-09 08:51:39.000000000 -0500 -+++ ./java/org/apache/catalina/session/LocalStrings.properties 2020-05-21 16:30:46.329792001 -0400 +--- ./java/org/apache/catalina/session/LocalStrings.properties.orig 2020-05-21 16:14:03.128513044 -0400 ++++ ./java/org/apache/catalina/session/LocalStrings.properties 2020-05-21 16:14:14.058488232 -0400 @@ -20,6 +20,7 @@ fileStore.loading=Loading Session {0} fr fileStore.removing=Removing Session {0} at file {1} fileStore.deleteFailed=Unable to delete file [{0}] which is preventing the creation of the session storage location @@ -56,13 +56,13 @@ diff -up ./java/org/apache/catalina/session/LocalStrings.properties.orig ./java/ JDBCStore.saving=Saving Session {0} to database {1} JDBCStore.loading=Loading Session {0} from database {1} diff -up ./webapps/docs/changelog.xml.orig ./webapps/docs/changelog.xml ---- ./webapps/docs/changelog.xml.orig 2020-05-21 16:30:46.338791987 -0400 -+++ ./webapps/docs/changelog.xml 2020-05-21 16:31:22.209735361 -0400 +--- ./webapps/docs/changelog.xml.orig 2020-05-21 16:14:22.575468899 -0400 ++++ ./webapps/docs/changelog.xml 2020-05-21 16:15:39.413294473 -0400 @@ -57,6 +57,15 @@ They eventually become mixed with the numbered issues. (I.e., numbered issues do not "pop up" wrt. others). --> -+
++
+ + + @@ -71,6 +71,6 @@ diff -up ./webapps/docs/changelog.xml.orig ./webapps/docs/changelog.xml + + +
-
- +
+ diff --git a/SOURCES/tomcat-7.0.76-rhbz-1795645.patch b/SOURCES/tomcat-7.0.76-rhbz-1795645.patch new file mode 100644 index 0000000..cdf3191 --- /dev/null +++ b/SOURCES/tomcat-7.0.76-rhbz-1795645.patch @@ -0,0 +1,394 @@ +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java +index b1510617e7..69ed482256 100644 +--- modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java +@@ -328,7 +328,10 @@ public class ConnectionPool { + next = next.getNext(); + } + } +- ++ // setup statement proxy ++ if (getPoolProperties().getUseStatementFacade()) { ++ handler = new StatementFacade(handler); ++ } + try { + getProxyConstructor(con.getXAConnection() != null); + //create the proxy +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java +index 120a6f6bdc..d0a41dfdff 100644 +--- modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java +@@ -125,6 +125,8 @@ public class DataSourceFactory implements ObjectFactory { + + protected static final String PROP_IGNOREEXCEPTIONONPRELOAD = "ignoreExceptionOnPreLoad"; + ++ protected static final String PROP_USESTATEMENTFACADE = "useStatementFacade"; ++ + public static final int UNKNOWN_TRANSACTIONISOLATION = -1; + + public static final String OBJECT_NAME = "object_name"; +@@ -180,7 +182,8 @@ public class DataSourceFactory implements ObjectFactory { + PROP_USEDISPOSABLECONNECTIONFACADE, + PROP_LOGVALIDATIONERRORS, + PROP_PROPAGATEINTERRUPTSTATE, +- PROP_IGNOREEXCEPTIONONPRELOAD ++ PROP_IGNOREEXCEPTIONONPRELOAD, ++ PROP_USESTATEMENTFACADE + }; + + // -------------------------------------------------- ObjectFactory Methods +@@ -528,7 +531,10 @@ public class DataSourceFactory implements ObjectFactory { + if (value != null) { + poolProperties.setIgnoreExceptionOnPreLoad(Boolean.parseBoolean(value)); + } +- ++ value = properties.getProperty(PROP_USESTATEMENTFACADE); ++ if (value != null) { ++ poolProperties.setUseStatementFacade(Boolean.parseBoolean(value)); ++ } + return poolProperties; + } + +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java +index b5d0c0a0ad..cea6370a92 100644 +--- modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java +@@ -1418,6 +1418,22 @@ public class DataSourceProxy implements PoolConfiguration { + getPoolProperties().setIgnoreExceptionOnPreLoad(ignoreExceptionOnPreLoad); + } + ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean getUseStatementFacade() { ++ return getPoolProperties().getUseStatementFacade(); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public void setUseStatementFacade(boolean useStatementFacade) { ++ getPoolProperties().setUseStatementFacade(useStatementFacade); ++ } ++ + public void purge() { + try { + createPool().purge(); +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java +index ae489a038e..b0f7f4f54b 100644 +--- modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java +@@ -889,4 +889,18 @@ public interface PoolConfiguration { + */ + public boolean isIgnoreExceptionOnPreLoad(); + ++ /** ++ * Set this to true if you wish to wrap statements in order to enable equals() and hashCode() ++ * methods to be called on the closed statements if any statement proxy is set. ++ * @param useStatementFacade set to true to wrap statements ++ */ ++ public void setUseStatementFacade(boolean useStatementFacade); ++ ++ /** ++ * Returns true if this connection pool is configured to wrap statements in order ++ * to enable equals() and hashCode() methods to be called on the closed statements if any ++ * statement proxy is set. ++ * @return true if the statements are wrapped ++ */ ++ public boolean getUseStatementFacade(); + } +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java +index 2a2131f008..070d1d0a4c 100644 +--- modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java +@@ -28,6 +28,7 @@ import java.util.Properties; + import java.util.concurrent.atomic.AtomicInteger; + + ++ + import org.apache.juli.logging.Log; + import org.apache.juli.logging.LogFactory; + +@@ -94,7 +95,7 @@ public class PoolProperties implements PoolConfiguration, Cloneable, Serializabl + private volatile boolean logValidationErrors = false; + private volatile boolean propagateInterruptState = false; + private volatile boolean ignoreExceptionOnPreLoad = false; +- ++ private volatile boolean useStatementFacade = true; + + /** + * {@inheritDoc} +@@ -1290,6 +1291,22 @@ public class PoolProperties implements PoolConfiguration, Cloneable, Serializabl + this.ignoreExceptionOnPreLoad = ignoreExceptionOnPreLoad; + } + ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean getUseStatementFacade() { ++ return useStatementFacade; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public void setUseStatementFacade(boolean useStatementFacade) { ++ this.useStatementFacade = useStatementFacade; ++ } ++ + @Override + protected Object clone() throws CloneNotSupportedException { + // TODO Auto-generated method stub +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java +new file mode 100644 +index 0000000000..f3c8e59d28 +--- /dev/null ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java +@@ -0,0 +1,177 @@ ++/* ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++ ++package org.apache.tomcat.jdbc.pool; ++ ++import java.lang.reflect.Constructor; ++import java.lang.reflect.InvocationHandler; ++import java.lang.reflect.InvocationTargetException; ++import java.lang.reflect.Method; ++import java.lang.reflect.Proxy; ++import java.sql.CallableStatement; ++import java.sql.PreparedStatement; ++import java.sql.Statement; ++ ++import org.apache.juli.logging.Log; ++import org.apache.juli.logging.LogFactory; ++import org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor; ++ ++public class StatementFacade extends AbstractCreateStatementInterceptor { ++ ++ private static final Log logger = LogFactory.getLog(StatementFacade.class); ++ ++ /** ++ * the constructors that are used to create statement proxies ++ */ ++ protected static final Constructor[] constructors ++ = new Constructor[AbstractCreateStatementInterceptor.STATEMENT_TYPE_COUNT]; ++ ++ protected StatementFacade(JdbcInterceptor interceptor) { ++ setUseEquals(interceptor.isUseEquals()); ++ setNext(interceptor); ++ } ++ ++ @Override ++ public void closeInvoked() { ++ // nothing to do ++ } ++ ++ /** ++ * Creates a statement interceptor to monitor query response times ++ */ ++ @Override ++ public Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time) { ++ try { ++ String name = method.getName(); ++ Constructor constructor = null; ++ String sql = null; ++ if (compare(CREATE_STATEMENT, name)) { ++ // createStatement ++ constructor = getConstructor(CREATE_STATEMENT_IDX, Statement.class); ++ } else if (compare(PREPARE_STATEMENT, name)) { ++ // prepareStatement ++ constructor = getConstructor(PREPARE_STATEMENT_IDX, PreparedStatement.class); ++ sql = (String)args[0]; ++ } else if (compare(PREPARE_CALL, name)) { ++ // prepareCall ++ constructor = getConstructor(PREPARE_CALL_IDX, CallableStatement.class); ++ sql = (String)args[0]; ++ } else { ++ // do nothing ++ return statement; ++ } ++ return constructor.newInstance(new Object[] { new StatementProxy(statement,sql) }); ++ } catch (Exception x) { ++ logger.warn("Unable to create statement proxy.", x); ++ } ++ return statement; ++ } ++ ++ /** ++ * Creates a constructor for a proxy class, if one doesn't already exist ++ * ++ * @param idx ++ * - the index of the constructor ++ * @param clazz ++ * - the interface that the proxy will implement ++ * @return - returns a constructor used to create new instances ++ * @throws NoSuchMethodException Constructor not found ++ */ ++ protected Constructor getConstructor(int idx, Class clazz) throws NoSuchMethodException { ++ if (constructors[idx] == null) { ++ Class proxyClass = Proxy.getProxyClass(StatementFacade.class.getClassLoader(), ++ new Class[] { clazz }); ++ constructors[idx] = proxyClass.getConstructor(new Class[] { InvocationHandler.class }); ++ } ++ return constructors[idx]; ++ } ++ ++ /** ++ * Class to measure query execute time. ++ */ ++ protected class StatementProxy implements InvocationHandler { ++ protected boolean closed = false; ++ protected Object delegate; ++ protected final String query; ++ public StatementProxy(Object parent, String query) { ++ this.delegate = parent; ++ this.query = query; ++ } ++ ++ @Override ++ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ++ if (compare(TOSTRING_VAL,method)) { ++ return toString(); ++ } ++ if (compare(EQUALS_VAL, method)) { ++ return Boolean.valueOf( ++ this.equals(Proxy.getInvocationHandler(args[0]))); ++ } ++ if (compare(HASHCODE_VAL, method)) { ++ return Integer.valueOf(this.hashCode()); ++ } ++ if (compare(CLOSE_VAL, method)) { ++ if (delegate == null) return null; ++ } ++ if (compare(ISCLOSED_VAL, method)) { ++ if (delegate == null) return true; ++ } ++ ++ Object result = null; ++ try { ++ //invoke next ++ result = method.invoke(delegate,args); ++ } catch (Throwable t) { ++ if (t instanceof InvocationTargetException && t.getCause() != null) { ++ throw t.getCause(); ++ } else { ++ throw t; ++ } ++ } ++ //perform close cleanup ++ if (compare(CLOSE_VAL, method)) { ++ delegate = null; ++ } ++ return result; ++ } ++ ++ @Override ++ public int hashCode() { ++ return System.identityHashCode(this); ++ } ++ ++ @Override ++ public boolean equals(Object obj) { ++ return this==obj; ++ } ++ ++ @Override ++ public String toString() { ++ StringBuffer buf = new StringBuffer(StatementProxy.class.getName()); ++ buf.append("[Proxy="); ++ buf.append(hashCode()); ++ buf.append("; Query="); ++ buf.append(query); ++ buf.append("; Delegate="); ++ buf.append(delegate); ++ buf.append("]"); ++ return buf.toString(); ++ } ++ } ++ ++} +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java +index 8eb0bfefa0..27928d19b3 100644 +--- modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java +@@ -916,6 +916,22 @@ public class ConnectionPool extends NotificationBroadcasterSupport implements Co + throw new UnsupportedOperationException(); + } + ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean getUseStatementFacade() { ++ return getPoolProperties().getUseStatementFacade(); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public void setUseStatementFacade(boolean useStatementFacade) { ++ getPoolProperties().setUseStatementFacade(useStatementFacade); ++ } ++ + /** + * {@inheritDoc} + */ +diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml +index 1694c80ae7..38b009fa03 100644 +--- modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml ++++ modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml +@@ -330,6 +330,12 @@ + is="true" + writeable="false"/> + ++ ++ + ++
++ ++ ++ ++ 60764: Implement equals() and ++ hashCode() in the StatementFacade in order to ++ enable these methods to be called on the closed statements if any ++ statement proxy is set. This behavior can be changed with ++ useStatementFacade attribute. (kfujino) ++ ++ ++ ++
+
+ + diff --git a/SOURCES/tomcat-7.0.76-rhbz-1822453.patch b/SOURCES/tomcat-7.0.76-rhbz-1822453.patch new file mode 100644 index 0000000..1c42de7 --- /dev/null +++ b/SOURCES/tomcat-7.0.76-rhbz-1822453.patch @@ -0,0 +1,10 @@ +--- ./java/org/apache/coyote/http11/AbstractHttp11Processor.java.orig 2020-04-09 12:07:26.128832599 +0900 ++++ ./java/org/apache/coyote/http11/AbstractHttp11Processor.java 2020-04-09 12:07:35.027847534 +0900 +@@ -1318,6 +1318,7 @@ + } + // Next 3 characters must be "://" + if (uriBC.startsWith("://", pos)) { ++ pos += 3; + int uriBCStart = uriBC.getStart(); + + // '/' does not appear in the authority so use the first diff --git a/SOURCES/tomcat-7.0.conf b/SOURCES/tomcat-7.0.conf index 07a1cf2..a01c2f4 100644 --- a/SOURCES/tomcat-7.0.conf +++ b/SOURCES/tomcat-7.0.conf @@ -34,6 +34,9 @@ CATALINA_TMPDIR="/var/cache/tomcat/temp" # Use JAVA_OPTS to set java.library.path for libtcnative.so #JAVA_OPTS="-Djava.library.path=/usr/lib" +# Set default javax.sql.DataSource factory to apache commons one. See rhbz#1629162 +JAVA_OPTS="-Djavax.sql.DataSource.Factory=org.apache.commons.dbcp.BasicDataSourceFactory" + # You can change your tomcat locale here #LANG="en_US" diff --git a/SOURCES/tomcat-named.service b/SOURCES/tomcat-named.service index 2998060..b6cd8bd 100644 --- a/SOURCES/tomcat-named.service +++ b/SOURCES/tomcat-named.service @@ -13,8 +13,8 @@ After=syslog.target network.target [Service] Type=simple EnvironmentFile=/etc/tomcat/tomcat.conf -Environment="NAME=%I" -EnvironmentFile=-/etc/sysconfig/tomcat@%I +Environment="NAME=%i" +EnvironmentFile=-/etc/sysconfig/tomcat@%i ExecStart=/usr/libexec/tomcat/server start ExecStop=/usr/libexec/tomcat/server stop SuccessExitStatus=143 diff --git a/SPECS/tomcat.spec b/SPECS/tomcat.spec index 21ea668..9578900 100644 --- a/SPECS/tomcat.spec +++ b/SPECS/tomcat.spec @@ -54,7 +54,7 @@ Name: tomcat Epoch: 0 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 12%{?dist} +Release: 15%{?dist} Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API Group: System Environment/Daemons @@ -102,7 +102,11 @@ Patch14: %{name}-7.0.76-CVE-2018-8034.patch Patch15: %{name}-7.0.76-rhbz-1588703.patch Patch16: %{name}-7.0.76-rhbz-1455483.patch Patch17: %{name}-7.0.76-CVE-2020-1938.patch -Patch18: %{name}-7.0.76-CVE-2020-9484.patch +Patch18: %{name}-7.0.76-rhbz-1822453.patch +Patch19: %{name}-7.0.76-rhbz-1795645.patch +Patch20: %{name}-7.0.76-CVE-2019-17563.patch +Patch21: %{name}-7.0.76-CVE-2020-9484.patch +Patch22: %{name}-7.0.76-CVE-2020-13935.patch BuildArch: noarch @@ -266,6 +270,10 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch16 -p0 %patch17 -p0 %patch18 -p0 +%patch19 -p0 +%patch20 -p0 +%patch21 -p0 +%patch22 -p0 %{__ln_s} $(build-classpath jakarta-taglibs-core) webapps/examples/WEB-INF/lib/jstl.jar %{__ln_s} $(build-classpath jakarta-taglibs-standard) webapps/examples/WEB-INF/lib/standard.jar @@ -710,11 +718,26 @@ fi %attr(0644,root,root) %{_unitdir}/%{name}-jsvc.service %changelog -* Thu May 21 2020 Coty Sutherland 0:7.0.76-12 +* Fri Jul 17 2020 Coty Sutherland 0:7.0.76-15 +- Resolves: CVE-2020-13935 tomcat: multiple requests with invalid payload length in a WebSocket frame could lead to DoS + +* Thu May 21 2020 Coty Sutherland 0:7.0.76-14 +- Revert rhbz#1814315 because it caused other issues with ipa-server, see rhbz#1831127 - Resolves: CVE-2020-9484 tomcat: Apache Tomcat Remote Code Execution via session persistence +* Wed May 06 2020 Coty Sutherland 0:7.0.76-13 +- Revert rhbz#1367492 because it caused issues with ipa-server, see rhbz#1831127 + +* Fri Apr 24 2020 Coty Sutherland 0:7.0.76-12 +- Resolves: rhbz#1367492 harden package permissions +- Resolves: rhbz#1523112 tomcat systemd does not cope with - in service names +- Resolves: rhbz#1629162 tomcat-dbcp.jar is missing from tomcat package +- Resolves: rhbz#1822453 Tomcat parses a request having an absolute URI path incorrectly and returns 404 Not Found +- Resolves: rhbz#1795645 connection leak with StatementCache, SlowQueryReport or StatementDecoratorInterceptor +- Resolves: CVE-2019-17563 tomcat: session fixation when using FORM authentication + * Tue Mar 03 2020 Coty Sutherland 0:7.0.76-11 -- Resolves: rhbz#1806802 CVE-2020-1938 tomcat: Apache Tomcat AJP File Read/Inclusion Vulnerability +- CVE-2020-1938 tomcat: Apache Tomcat AJP File Read/Inclusion Vulnerability * Tue Sep 03 2019 Coty Sutherland 0:7.0.76-10 - Resolves: rhbz#1748541 Bump tomcat release number