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