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

Fix disposing root X.509 certificate prematurely for OCSP stapling #82116

Merged
merged 5 commits into from
Feb 17, 2023

Conversation

vcsjones
Copy link
Member

@vcsjones vcsjones commented Feb 14, 2023

Fixes #81964

This fixes an issue where we were capturing the root certificate for OCSP stapling purposes, however would dispose of the certificate when we needed it. This resulted in a null Handle, which would be fed in to OpenSSL and cause a null deref in native code, crashing the .NET process. This scenario only occurred in two-element certificate chains. If there was an intermediate in the chain, the issue does not occur.

This PR addresses this in two ways. First, it stops disposing of the root certificate when it is needed. Some platforms and Linux situations don't need the root, and in that scenario, it gets disposed. The second is to actually check the Handle prior to handing it off to native code with an Assert. Additionally, in release configurations, this will simply exit the OCSP stapling and return a null response, and further prevent future staples for happening in that context.

Lastly, this adds tests for two-element chains. Prior to the fix, the tests would segfault as reported by the customer.

Contributes to #81964

This defers disposal of the root certificate when it might be needed for OCSP staple fetching.
Before this change, the root certificate would get disposed, giving it a null handle. We would then
use this null handle when attempting to build an OCSP request, which OpenSSL would null-deref.

For platforms that don't need the root certificate, they dispose of it.
Even though we've fixed the null pointer being passed now, add some defenses so that if we are somehow given a null handle some time in the future, we skip OCSP stapling instead of null derefing in native code.
@ghost
Copy link

ghost commented Feb 14, 2023

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

This fixes an issue where we were capturing the root certificate for OCSP stapling purposes, however would dispose of the certificate when we needed it. This resulted in a null Handle, which would be fed in to OpenSSL and cause a null deref in native code, crashing the .NET process. This scenario only occurred in two-element certificate chains. If there was an intermediate in the chain, the issue does not occur.

This PR addresses this in two ways. First, it stops disposing of the root certificate when it is needed. Some platforms and Linux situations don't need the root, and in that scenario, it gets disposed. The second is to actually check the Handle prior to handing it off to native code with an Assert. Additionally, in release configurations, this will simply exit the OCSP stapling and return a null response, and further prevent future staples for happening in that context.

Lastly, this adds tests for two-element chains. Prior to the fix, the tests would segfault as reported by the customer.

Contributes to #81964

Author: vcsjones
Assignees: vcsjones
Labels:

area-System.Net.Security

Milestone: -

@vcsjones
Copy link
Member Author

@bartonjs this slightly deviates from our discussion earlier, and I'll attempt to explain why. First, with this approach we don't need to duplicate the certificate as we previously discussed. Instead, the platform decides if it cares to keep the root or not.

Second, we can't do AddRootCertificate earlier before the disposal because that's an instance member on ctx - and that needs the intermediates for the constructor.

Copy link
Member

@bartonjs bartonjs left a comment

Choose a reason for hiding this comment

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

Left a suggestion to reduce the number of places we need to repeat the implementation of a partial method; otherwise LGTM.

@vcsjones
Copy link
Member Author

/azp run runtime-libraries-coreclr outerloop-linux

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@vcsjones
Copy link
Member Author

I only ran the outerloop tests for linux since the test and changes only affect Linux. The failures in outerloop look irrelevant to me, as the two new test cases passed in all legs.

@bartonjs bartonjs merged commit 9e6f172 into dotnet:main Feb 17, 2023
@bartonjs
Copy link
Member

/backport to release/7.0

@github-actions
Copy link
Contributor

Started backporting to release/7.0: https://github.com/dotnet/runtime/actions/runs/4199504897

@vcsjones vcsjones deleted the fix-81964 branch February 17, 2023 13:13
@ghost ghost locked as resolved and limited conversation to collaborators Mar 19, 2023
@karelz karelz added this to the 8.0.0 milestone Mar 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Kestrel: Segfault when specifying default certificate on Ubuntu 20.04
4 participants