-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UNDERTOW-2424: Prevent connection access-after-free allowed through ChunkedStreamSinkConduit #1648
Conversation
…hunkedStreamSinkConduit ChunkedStreamSinkConduit releases underlying connections for reuse via a conduit listener, however flush calls may still be passed through after writes are terminated and successfully flushed. This would cause requests to be clobbered when the connection had already been reused to send another request, breaking the threading model.
Specifics of the scenario in #1495: (note that line numbers may be slightly off due to debug statements I added in testing, method names/paths should be equivalent) The exchange is completed here:
However undertow/core/src/main/java/io/undertow/conduits/DeflatingStreamSinkConduit.java Lines 376 to 377 in 182e4ca
with roughly this stack trace:
The problem is, once the exchange ended, another request has already been parsed, so a |
@@ -200,6 +200,9 @@ int doWrite(final ByteBuffer src) throws IOException { | |||
|
|||
@Override | |||
public void truncateWrites() throws IOException { | |||
if (anyAreSet(state, FLAG_FINISHED)) { | |||
return; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have another subtle bug in this method. The invokeFinishListener()
is called prior to the finally
, so the connection may already be used by another thread by the time we call truncateWrites
. I'll push an update shortly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, this shouldn't matter in practice because terminateWrites will close the underlying persistent connection, so we don't need to worry about reuse.
Jira: https://issues.redhat.com/browse/UNDERTOW-2424
2.2.x PR: #1652
2.3.x PR: #1653
ChunkedStreamSinkConduit releases underlying connections for reuse via a conduit listener, however flush calls may still be passed through after writes are terminated and successfully flushed. This would cause requests to be clobbered when the connection had already been reused to send another request, breaking the threading model.
This resolves the issue from #1495
For posterity: My first attempt at a fix was #1645 which resolves the issue, but I think this PR is cleaner and more precise. As always, I'm happy to throw the code out if you prefer a different approach, the important piece is the analysis of the root cause of the failures, which I believe I understand at this point :-)