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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org