Fix TlsHandler.FinishWrap null promise masking AuthenticationException#61
Open
maksimkim wants to merge 2 commits into
Open
Fix TlsHandler.FinishWrap null promise masking AuthenticationException#61maksimkim wants to merge 2 commits into
maksimkim wants to merge 2 commits into
Conversation
Fix four interrelated bugs that cause NullReferenceException to mask the real AuthenticationException when TLS certificate validation fails: 1. Add catch clause in Decode's error handler so WrapAndFlush exceptions don't mask the original cause 2. Null-check Remove() return in Wrap to handle queue drained by re-entrant HandleFailure 3. Guard FinishWrap/FinishWrapNonAppData with _outboundClosed check to short-circuit writes after failure 4. Wrap _sslStream.Dispose() in Close with try-catch to prevent dispose exceptions from propagating Fixes #60 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
833037a to
088649e
Compare
Use a custom Stream wrapper (QueueDrainingStreamWrapper) around MediationStream to simulate the re-entrant HandleFailure scenario: after SslStream encrypts data and writes ciphertext to MediationStream (which sets _lastContextWriteTask via FinishWrap), the wrapper drains the pending write queue and clears _lastContextWriteTask. When Wrap continues, Remove() returns null and the unfixed code hits promise.TryComplete() on a null promise, producing NRE. Verified: test FAILS on all 3 TFMs (net452, net471, netcoreapp2.1) without Fix 2, and PASSES with Fix 2 applied. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Owner
Author
|
/azp run |
Owner
Author
|
@copilot why ci pipelines were not executed on this PR? |
I checked the CI config and run history: this repo currently has no regular GitHub Actions CI workflow, and the Azure pipeline YAML ( |
Owner
Author
|
/azp run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #60 — When TLS certificate validation fails, a
NullReferenceExceptionfromWrap/FinishWrapmasks the realAuthenticationException.Root Cause
Two interrelated bugs combine to replace the original
AuthenticationExceptionwith aNullReferenceException:Decode's catch block callsWrapAndFlushin atry/finallywith nocatch— ifWrapAndFlushthrows, its exception replaces the original cause.Wrapmethod calls_pendingUnencryptedWrites.Remove()without null-checking —Remove()returnsnullwhen the queue was drained re-entrantly byHandleFailure→RemoveAndFailAll.Changes
Fix 1: Catch
WrapAndFlushexceptions inDecode(TlsHandler.Reader.cs)Added
catch (Exception) { }clause soWrapAndFlushexceptions don't mask the original cause.Fix 2: Null-check
Remove()return inWrap(TlsHandler.Writer.cs)Added
if (promise is null) { break; }afterRemove()to handle the queue being drained externally.Fix 3: Guard
FinishWrap/FinishWrapNonAppData(TlsHandler.Writer.cs)Added
_outboundClosedcheck at the start of all four overloads to short-circuit writes after the handler enters a failure state.Fix 4: Protect
_sslStream.Dispose()inClose(TlsHandler.cs)Wrapped
_sslStream.Dispose()in try-catch to prevent dispose exceptions from propagating during channel close.Regression test (
TlsHandlerTest.cs)Added
CertValidationRejection_ShouldNotThrowNullReferenceException— configures a TLS client that rejects the server certificate and verifies theTlsHandshakeCompletionEventcontains the real exception, not aNullReferenceException.