From 4c04369c287233ea2e8e5135f6c31d02e2d76293 Mon Sep 17 00:00:00 2001 From: Mark Thomas Date: Mon, 6 Aug 2018 14:44:23 +0000 Subject: [PATCH] Add some comments for the fix for CVE-2018-8037 git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1837530 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/coyote/AbstractProcessor.java | 9 +++++++++ java/org/apache/coyote/AsyncStateMachine.java | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/java/org/apache/coyote/AbstractProcessor.java b/java/org/apache/coyote/AbstractProcessor.java index 5be2cb8c1f03..67acb3f2cc61 100644 --- a/java/org/apache/coyote/AbstractProcessor.java +++ b/java/org/apache/coyote/AbstractProcessor.java @@ -51,6 +51,15 @@ public abstract class AbstractProcessor extends AbstractProcessorLight implement protected final Adapter adapter; protected final AsyncStateMachine asyncStateMachine; private volatile long asyncTimeout = -1; + /* + * Tracks the current async generation when a timeout is dispatched. In the + * time it takes for a container thread to be allocated and the timeout + * processing to start, it is possible that the application completes this + * generation of async processing and starts a new one. If the timeout is + * then processed against the new generation, response mix-up can occur. + * This field is used to ensure that any timeout event processed is for the + * current async generation. This prevents the response mix-up. + */ private volatile long asyncTimeoutGeneration = 0; protected final Request request; protected final Response response; diff --git a/java/org/apache/coyote/AsyncStateMachine.java b/java/org/apache/coyote/AsyncStateMachine.java index 946ce42868b6..0cb3348ca545 100644 --- a/java/org/apache/coyote/AsyncStateMachine.java +++ b/java/org/apache/coyote/AsyncStateMachine.java @@ -190,6 +190,14 @@ boolean isCompleting() { private volatile AsyncState state = AsyncState.DISPATCHED; private volatile long lastAsyncStart = 0; + /* + * Tracks the current generation of async processing for this state machine. + * The generation is incremented every time async processing is started. The + * primary purpose of this is to enable Tomcat to detect and prevent + * attempts to process an event for a previous generation with the current + * generation as processing such an event usually ends badly: + * e.g. CVE-2018-8037. + */ private final AtomicLong generation = new AtomicLong(0); // Need this to fire listener on complete private AsyncContextCallback asyncCtxt = null;