This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 10.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.0.x by this push:
     new c13a76f  Protect against a known OS bug
c13a76f is described below

commit c13a76f78bb1e4988a787f354a1be82e67d87186
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Nov 17 18:48:33 2021 +0000

    Protect against a known OS bug
    
    https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1924298
---
 java/org/apache/tomcat/util/net/AprEndpoint.java        | 15 +++++++++++++++
 java/org/apache/tomcat/util/net/LocalStrings.properties |  1 +
 java/org/apache/tomcat/util/net/Nio2Endpoint.java       | 12 +++++++++++-
 java/org/apache/tomcat/util/net/NioEndpoint.java        | 11 ++++++++++-
 webapps/docs/changelog.xml                              |  6 ++++++
 5 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/AprEndpoint.java 
b/java/org/apache/tomcat/util/net/AprEndpoint.java
index 7b93b3d..578a571 100644
--- a/java/org/apache/tomcat/util/net/AprEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AprEndpoint.java
@@ -116,6 +116,9 @@ public class AprEndpoint extends 
AbstractEndpoint<Long,Long> implements SNICallB
     protected long sslContext = 0;
 
 
+    private int previousAcceptedPort = -1;
+    private String previousAcceptedAddress = null;
+
     // ------------------------------------------------------------ Constructor
 
     public AprEndpoint() {
@@ -794,7 +797,18 @@ public class AprEndpoint extends 
AbstractEndpoint<Long,Long> implements SNICallB
             if (log.isDebugEnabled()) {
                 log.debug(sm.getString("endpoint.debug.socket", socket));
             }
+
+            // Do the duplicate accept check here rather than in 
serverSocketaccept()
+            // so we can cache the results in the SocketWrapper
             AprSocketWrapper wrapper = new AprSocketWrapper(socket, this);
+            if (wrapper.getRemotePort() == previousAcceptedPort) {
+                if (wrapper.getRemoteAddr().equals(previousAcceptedAddress)) {
+                    throw new 
IOException(sm.getString("endpoint.err.duplicateAccept"));
+                }
+            }
+            previousAcceptedPort = wrapper.getRemotePort();
+            previousAcceptedAddress = wrapper.getRemoteAddr();
+
             connections.put(socket, wrapper);
             wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
             wrapper.setReadTimeout(getConnectionTimeout());
@@ -815,6 +829,7 @@ public class AprEndpoint extends 
AbstractEndpoint<Long,Long> implements SNICallB
 
     @Override
     protected Long serverSocketAccept() throws Exception {
+        // See setSocketOptions(Long) for duplicate accept check
         long socket = Socket.accept(serverSock);
         if (socket == 0) {
             throw new IOException(sm.getString("endpoint.err.accept", 
getName()));
diff --git a/java/org/apache/tomcat/util/net/LocalStrings.properties 
b/java/org/apache/tomcat/util/net/LocalStrings.properties
index 3e306ec..0cc32e4 100644
--- a/java/org/apache/tomcat/util/net/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/net/LocalStrings.properties
@@ -82,6 +82,7 @@ endpoint.duplicateSslHostName=Multiple SSLHostConfig elements 
were provided for
 endpoint.err.accept=Failed to accept socket for end point [{0}]
 endpoint.err.attach=Failed to attach SSLContext to socket - error [{0}]
 endpoint.err.close=Caught exception trying to close socket
+endpoint.err.duplicateAccept=Duplicate accept detected. This is a known OS 
bug. Please consider reporting that you are affected: 
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1924298
 endpoint.err.handshake=Handshake failed
 endpoint.err.unexpected=Unexpected error processing socket
 endpoint.executor.fail=Executor rejected socket [{0}] for processing
diff --git a/java/org/apache/tomcat/util/net/Nio2Endpoint.java 
b/java/org/apache/tomcat/util/net/Nio2Endpoint.java
index be724c4..c46a3c4 100644
--- a/java/org/apache/tomcat/util/net/Nio2Endpoint.java
+++ b/java/org/apache/tomcat/util/net/Nio2Endpoint.java
@@ -84,6 +84,8 @@ public class Nio2Endpoint extends 
AbstractJsseEndpoint<Nio2Channel,AsynchronousS
      */
     private SynchronizedStack<Nio2Channel> nioChannels;
 
+    private SocketAddress previousAcceptedSocketRemoteAddress = null;
+
     // --------------------------------------------------------- Public Methods
 
 
@@ -355,7 +357,15 @@ public class Nio2Endpoint extends 
AbstractJsseEndpoint<Nio2Channel,AsynchronousS
 
     @Override
     protected AsynchronousSocketChannel serverSocketAccept() throws Exception {
-        return serverSock.accept().get();
+        AsynchronousSocketChannel result = serverSock.accept().get();
+
+        SocketAddress currentRemoteAddress = result.getRemoteAddress();
+        if (currentRemoteAddress.equals(previousAcceptedSocketRemoteAddress)) {
+            throw new 
IOException(sm.getString("endpoint.err.duplicateAccept"));
+        }
+        previousAcceptedSocketRemoteAddress = currentRemoteAddress;
+
+        return result;
     }
 
 
diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java 
b/java/org/apache/tomcat/util/net/NioEndpoint.java
index 338c0d0..4950fca 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -108,6 +108,8 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
      */
     private SynchronizedStack<NioChannel> nioChannels;
 
+    private SocketAddress previousAcceptedSocketRemoteAddress = null;
+
 
     // ------------------------------------------------------------- Properties
 
@@ -510,7 +512,14 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
 
     @Override
     protected SocketChannel serverSocketAccept() throws Exception {
-        return serverSock.accept();
+        SocketChannel result = serverSock.accept();
+        SocketAddress currentRemoteAddress = result.getRemoteAddress();
+        if (currentRemoteAddress.equals(previousAcceptedSocketRemoteAddress)) {
+            throw new 
IOException(sm.getString("endpoint.err.duplicateAccept"));
+        }
+        previousAcceptedSocketRemoteAddress = currentRemoteAddress;
+
+        return result;
     }
 
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ce7c169..ea22b3e 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -115,6 +115,12 @@
         Improve error handling if APR/Native fails to accept an incoming
         connection. (markt)
       </fix>
+      <add>
+        Provide protection against a known <a
+        href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1924298";>OS
+        bug</a> that causes the acceptor to report an incoming connection more
+        than once. (markt)
+      </add>
     </changelog>
   </subsection>
 </section>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to