Skip to content
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

Fixes #4217 - SslConnection.DecryptedEnpoint.flush eternal busy loop. #4218

Merged

Conversation

sbordet
Copy link
Contributor

@sbordet sbordet commented Oct 17, 2019

#4217

Releasing the encrypted output buffer so that it can be re-acquired
with an expanded capacity.

Signed-off-by: Simone Bordet [email protected]

Releasing the encrypted output buffer so that it can be re-acquired
with an expanded capacity.

Signed-off-by: Simone Bordet <[email protected]>
Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix looks OK to me, but do we have a possible similar problem in fill?

@sbordet
Copy link
Contributor Author

sbordet commented Oct 18, 2019

@gregw in fill() we handle the BUFFER_UNDERFLOW correctly, but we don't handle the BUFFER_OVERFLOW that this issue would potentially generate. Instead we end up in the default case and throw IllegalStateException. Harsh, but we don't spin.

Handling BUFFER_OVERFLOW would be this:

case BUFFER_OVERFLOW:
    if (BufferUtil.isEmpty(_decryptedInput))
    {
        releaseDecryptedInputBuffer();
        continue;
    }
    throw new IllegalStateException();

The idea is that we release the too small application buffer we decrypt into, and loop around to get a new _decryptedInput with a larger capacity.
However, now we do spin around; if - for any reason - turns out that the capacity is the same as before and unwrap() still produces BUFFER_OVERFLOW then now we spin loop.

The same problem may happen in flush() with the fix in 2e633a4: wrap() returns BUFFER_UNDERFLOW, we release encrypted output, loop around, get a new buffer, but if the capacity is the same and wrap() returns BUFFER_UNDERFLOW again we spin loop.

The change to handle the fill() side is trivial. Do you think we should do it?

@gregw
Copy link
Contributor

gregw commented Oct 18, 2019

I now think that we should only do the reallocate loop if we know the buffer size has changed.

We should do for both fill and flush

Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check if the buffer capacity differs from the sllEngine size before reallocating and looping

Releasing the decrypted input buffer so that it can be re-acquired
with an expanded capacity.
Looping around only if the buffer size has changed.

Signed-off-by: Simone Bordet <[email protected]>
@sbordet sbordet requested a review from gregw October 19, 2019 10:30
Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than a minor question

SSLSession hsSession = _sslEngine.getHandshakeSession();
SSLSession session = _sslEngine.getSession();
int size = session.getApplicationBufferSize();
if (hsSession == null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it worthwhile doing

if (hsSession == null || hsSession == session)

or can they never be the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, will add that.

@gregw
Copy link
Contributor

gregw commented Oct 19, 2019

Also would be good to have a test, even one that just sent a hand crafted 5 byte frame.

@sbordet
Copy link
Contributor Author

sbordet commented Oct 19, 2019

@gregw will try to craft a test case... the test that I removed was failing because it was not causing the buffer expansion and now that SslConnection has the additional check on the buffer size it was aborting and thus failing the test.

Updates after review.
Added test case.

Signed-off-by: Simone Bordet <[email protected]>
@sbordet sbordet requested a review from gregw October 19, 2019 18:06
@sbordet
Copy link
Contributor Author

sbordet commented Oct 19, 2019

@gregw updated and wrote a test case.

Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@sbordet sbordet merged commit add8ffc into jetty-9.4.x Oct 21, 2019
@sbordet sbordet deleted the jetty-9.4.x-4217-tls_flush_buffer_overflow_busy_loop branch October 21, 2019 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants