You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2021/11/22 15:04:27 UTC

[tomcat] branch 8.5.x updated: Protect against a known OS bug

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

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


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

commit 01158bcb397d38ea749df38c848cf0e327f266e2
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Nov 22 14:30:31 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        | 17 +++++++++++++++++
 java/org/apache/tomcat/util/net/LocalStrings.properties |  1 +
 java/org/apache/tomcat/util/net/Nio2Endpoint.java       |  9 +++++++++
 java/org/apache/tomcat/util/net/NioEndpoint.java        |  9 +++++++++
 webapps/docs/changelog.xml                              |  6 ++++++
 5 files changed, 42 insertions(+)

diff --git a/java/org/apache/tomcat/util/net/AprEndpoint.java b/java/org/apache/tomcat/util/net/AprEndpoint.java
index 8556040..52bbd31 100644
--- a/java/org/apache/tomcat/util/net/AprEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AprEndpoint.java
@@ -107,6 +107,10 @@ public class AprEndpoint extends AbstractEndpoint<Long> implements SNICallBack {
     protected long sslContext = 0;
 
 
+    private int previousAcceptedPort = -1;
+    private String previousAcceptedAddress = null;
+
+
     private final Map<Long,AprSocketWrapper> connections = new ConcurrentHashMap<>();
 
 
@@ -752,7 +756,18 @@ public class AprEndpoint extends AbstractEndpoint<Long> implements SNICallBack {
                     log.debug(sm.getString("endpoint.debug.socket",
                             Long.valueOf(socket)));
                 }
+
+                // Do the duplicate accept check here rather than in Acceptor.run()
+                // so we can cache the results in the SocketWrapper
                 AprSocketWrapper wrapper = new AprSocketWrapper(Long.valueOf(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();
+
                 wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
                 wrapper.setReadTimeout(getConnectionTimeout());
                 wrapper.setWriteTimeout(getConnectionTimeout());
@@ -905,6 +920,8 @@ public class AprEndpoint extends AbstractEndpoint<Long> implements SNICallBack {
                     try {
                         // Accept the next incoming connection from the server
                         // socket
+                        // See processSocketWithOptions(long) for duplicate
+                        // accept check
                         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 dccd14b..ee1013a 100644
--- a/java/org/apache/tomcat/util/net/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/net/LocalStrings.properties
@@ -79,6 +79,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 84a8303..0093a45 100644
--- a/java/org/apache/tomcat/util/net/Nio2Endpoint.java
+++ b/java/org/apache/tomcat/util/net/Nio2Endpoint.java
@@ -83,6 +83,8 @@ public class Nio2Endpoint extends AbstractJsseEndpoint<Nio2Channel> {
      */
     private SynchronizedStack<Nio2Channel> nioChannels;
 
+    private SocketAddress previousAcceptedSocketRemoteAddress = null;
+
 
     public Nio2Endpoint() {
         // Override the defaults for NIO2
@@ -408,6 +410,13 @@ public class Nio2Endpoint extends AbstractJsseEndpoint<Nio2Channel> {
                         // Accept the next incoming connection from the server
                         // socket
                         socket = serverSock.accept().get();
+
+                        SocketAddress currentRemoteAddress = socket.getRemoteAddress();
+                        if (currentRemoteAddress.equals(previousAcceptedSocketRemoteAddress)) {
+                            throw new IOException(sm.getString("endpoint.err.duplicateAccept"));
+                        }
+                        previousAcceptedSocketRemoteAddress = currentRemoteAddress;
+
                     } catch (Exception e) {
                         // We didn't get a socket
                         countDownConnection();
diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java
index 6826985..54458aa 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
+import java.net.SocketAddress;
 import java.net.SocketTimeoutException;
 import java.nio.ByteBuffer;
 import java.nio.channels.CancelledKeyException;
@@ -102,6 +103,8 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel> {
      */
     private SynchronizedStack<NioChannel> nioChannels;
 
+    private SocketAddress previousAcceptedSocketRemoteAddress = null;
+
 
     // ------------------------------------------------------------- Properties
 
@@ -507,6 +510,12 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel> {
                         // Accept the next incoming connection from the server
                         // socket
                         socket = serverSock.accept();
+
+                        SocketAddress currentRemoteAddress = socket.getRemoteAddress();
+                        if (currentRemoteAddress.equals(previousAcceptedSocketRemoteAddress)) {
+                            throw new IOException(sm.getString("endpoint.err.duplicateAccept"));
+                        }
+                        previousAcceptedSocketRemoteAddress = currentRemoteAddress;
                     } catch (IOException ioe) {
                         // We didn't get a socket
                         countDownConnection();
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ea16c3a..3d60511 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -112,6 +112,12 @@
         A crash could occur if the connector was stopped whilst a connection was
         performing a TLS handshake. (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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org