From 8da31e8364c695240bda8026ac7338fb98ff12a3 Mon Sep 17 00:00:00 2001 From: zhangying Date: Thu, 28 Dec 2023 16:23:40 +0800 Subject: [PATCH] Fix CVE-2021-43980 Signed-off-by: zhangying --- CVE-2021-43980.patch | 158 +++++++++++++++++++++++++++++++++++++++++++ tomcat.spec | 6 +- 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 CVE-2021-43980.patch diff --git a/CVE-2021-43980.patch b/CVE-2021-43980.patch new file mode 100644 index 0000000..bb34389 --- /dev/null +++ b/CVE-2021-43980.patch @@ -0,0 +1,158 @@ +From 5bce81d5f92a2cda4037c0e5147b42382c8e4690 Mon Sep 17 00:00:00 2001 +From: zhangliangpengkun +Date: Sat, 18 Mar 2023 16:02:12 +0800 +Subject: [PATCH] 2 + +--- + java/org/apache/coyote/AbstractProtocol.java | 29 +++++++++---------- + .../tomcat/util/net/SocketWrapperBase.java | 17 +++++++++++- + 2 files changed, 30 insertions(+), 16 deletions(-) + +diff --git a/java/org/apache/coyote/AbstractProtocol.java b/java/org/apache/coyote/AbstractProtocol.java +index b5c4d5b..83caeb9 100644 +--- a/java/org/apache/coyote/AbstractProtocol.java ++++ b/java/org/apache/coyote/AbstractProtocol.java +@@ -677,7 +677,11 @@ public abstract class AbstractProtocol implements ProtocolHandler, + + S socket = wrapper.getSocket(); + +- Processor processor = connections.get(socket); ++ // We take complete ownership of the Processor inside of this method to ensure ++ // no other thread can release it while we're using it. Whatever processor is ++ // held by this variable will be associated with the SocketWrapper before this ++ // method returns. ++ Processor processor = (Processor) wrapper.takeCurrentProcessor(); + if (getLog().isDebugEnabled()) { + getLog().debug(sm.getString("abstractConnectionHandler.connectionsGet", + processor, socket)); +@@ -756,9 +760,6 @@ public abstract class AbstractProtocol implements ProtocolHandler, + processor.setSslSupport( + wrapper.getSslSupport(getProtocol().getClientCertProvider())); + +- // Associate the processor with the connection +- connections.put(socket, processor); +- + SocketState state = SocketState.CLOSED; + do { + state = processor.process(wrapper, status); +@@ -778,8 +779,6 @@ public abstract class AbstractProtocol implements ProtocolHandler, + release(processor); + // Create the upgrade processor + processor = upgradeProtocol.getProcessor(wrapper, getProtocol().getAdapter()); +- // Associate with the processor with the connection +- connections.put(socket, processor); + } else { + if (getLog().isDebugEnabled()) { + getLog().debug(sm.getString( +@@ -799,8 +798,6 @@ public abstract class AbstractProtocol implements ProtocolHandler, + getLog().debug(sm.getString("abstractConnectionHandler.upgradeCreate", + processor, wrapper)); + } +- // Associate with the processor with the connection +- connections.put(socket, processor); + // Initialise the upgrade handler (which may trigger + // some IO using the new protocol which is why the lines + // above are necessary) +@@ -832,8 +829,8 @@ public abstract class AbstractProtocol implements ProtocolHandler, + } else if (state == SocketState.OPEN) { + // In keep-alive but between requests. OK to recycle + // processor. Continue to poll for the next request. +- connections.remove(socket); + release(processor); ++ processor = null; + wrapper.registerReadInterest(); + } else if (state == SocketState.SENDFILE) { + // Sendfile in progress. If it fails, the socket will be +@@ -856,8 +853,7 @@ public abstract class AbstractProtocol implements ProtocolHandler, + } else { + // Connection closed. OK to recycle the processor. Upgrade + // processors are not recycled. +- connections.remove(socket); +- if (processor.isUpgrade()) { ++ if (processor != null && processor.isUpgrade()) { + UpgradeToken upgradeToken = processor.getUpgradeToken(); + HttpUpgradeHandler httpUpgradeHandler = upgradeToken.getHttpUpgradeHandler(); + InstanceManager instanceManager = upgradeToken.getInstanceManager(); +@@ -879,6 +875,11 @@ public abstract class AbstractProtocol implements ProtocolHandler, + } + } else { + release(processor); ++ processor = null; ++ } ++ ++ if (processor != null) { ++ wrapper.setCurrentProcessor(processor); + } + } + return state; +@@ -911,7 +912,6 @@ public abstract class AbstractProtocol implements ProtocolHandler, + + // Make sure socket/processor is removed from the list of current + // connections +- connections.remove(socket); + release(processor); + return SocketState.CLOSED; + } +@@ -937,7 +937,7 @@ public abstract class AbstractProtocol implements ProtocolHandler, + + /** + * Expected to be used by the handler once the processor is no longer +- * required. ++ * required. Care must be taken to ensure that this method is only + * + * @param processor Processor being released (that was associated with + * the socket) +@@ -964,8 +964,7 @@ public abstract class AbstractProtocol implements ProtocolHandler, + */ + @Override + public void release(SocketWrapperBase socketWrapper) { +- S socket = socketWrapper.getSocket(); +- Processor processor = connections.remove(socket); ++ Processor processor = (Processor) socketWrapper.takeCurrentProcessor(); + release(processor); + } + +diff --git a/java/org/apache/tomcat/util/net/SocketWrapperBase.java b/java/org/apache/tomcat/util/net/SocketWrapperBase.java +index f8a79db..7362d27 100644 +--- a/java/org/apache/tomcat/util/net/SocketWrapperBase.java ++++ b/java/org/apache/tomcat/util/net/SocketWrapperBase.java +@@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; + import java.util.concurrent.locks.Lock; + import java.util.concurrent.locks.ReentrantReadWriteLock; + import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; ++import java.util.concurrent.atomic.AtomicReference; + + import org.apache.juli.logging.Log; + import org.apache.juli.logging.LogFactory; +@@ -91,7 +92,7 @@ public abstract class SocketWrapperBase { + * The max size of the buffered write buffer + */ + protected int bufferedWriteSize = 64 * 1024; // 64k default write buffer +- ++ private final AtomicReference currentProcessor = new AtomicReference<>(); + public SocketWrapperBase(E socket, AbstractEndpoint endpoint) { + this.socket = socket; + this.endpoint = endpoint; +@@ -103,6 +104,20 @@ public abstract class SocketWrapperBase { + public E getSocket() { + return socket; + } ++ ++ public Object getCurrentProcessor() { ++ return currentProcessor.get(); ++ } ++ ++ public void setCurrentProcessor(Object currentProcessor) { ++ this.currentProcessor.set(currentProcessor); ++ } ++ ++ public Object takeCurrentProcessor() { ++ return currentProcessor.getAndSet(null); ++ } ++ ++ + + protected AbstractEndpoint getEndpoint() { + return endpoint; +-- +2.33.0 diff --git a/tomcat.spec b/tomcat.spec index c619ab5..02b56d6 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -13,7 +13,7 @@ Name: tomcat Epoch: 1 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 32 +Release: 33 Summary: Implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies License: ASL 2.0 URL: http://tomcat.apache.org/ @@ -106,6 +106,7 @@ Patch6071: CVE-2023-28708-pre.patch Patch6072: CVE-2023-28708.patch Patch6073: CVE-2023-41080.patch Patch6074: CVE-2023-45648.patch +Patch6075: CVE-2021-43980.patch BuildRequires: ecj >= 1:4.6.1 findutils apache-commons-collections apache-commons-daemon BuildRequires: apache-commons-dbcp apache-commons-pool tomcat-taglibs-standard ant @@ -506,6 +507,9 @@ fi %{_javadocdir}/%{name} %changelog +* Thu Dec 28 2023 zhangying - 1:9.0.10-33 +- Fix CVE-2021-43980 + * Fri Oct 20 2023 wangkai <13474090681@163.com> - 1:9.0.10-32 - Fix CVE-2023-45648 -- Gitee