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