-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Fix OpenSSL 3 reporting an OutOfMemoryException for missing private key #63804
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
Conversation
|
Tagging subscribers to this area: @dotnet/area-system-security, @vcsjones, @krwq |
| return -2; | ||
| } | ||
|
|
||
| return -1; |
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.
In the malloc error case here, do we need to manipulate the queue in any way? (e.g. is this checking the same end of the queue that we use as the basis of a throw?)
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.
e.g. is this checking the same end of the queue that we use as the basis of a throw?
It's not, because that is what we are trying not to do. If we check the same end as the basis of the throw, then we are going to throw an OutOfMemoryException. We can't tell the difference between an OOM and "no private key". I though the next best thing we could do is check to see if the most-recent error thrown is an OOM. In that case, since we are peeking, it Weill just get thrown as-is.
Unfortunately I could not find a lot of flexibility in OpenSSL's error APIs. There is no way to examine the queue without consuming it, beyond peeking at the most recent item. Also, there is no way to determine the depth of the queue, as far as I could tell.
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're talking about opposing conditions 😄
If the error isn't malloc, we return -2. The caller special cases that throw.
If the error is malloc, we return -1. The caller then throws an exception. I believe we want it to throw OOM, and I'm just making sure that the error reported by ERR_peek_error() is the one we're going to end up with in the throw... but I believe that we currently throw ERR_peek_last_error().
We could bridge that gap with something like
const char* file;
const char* line;
ERR_peek_error_line(&file, &line);
ERR_put_error(ERR_GET_LIB(error), ERR_GET_FUNC(error), ERR_GET_REASON(err), file, line);
return -1;which would copy the head to the tail (until we revisit our exception model)
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.
(until we revisit our exception model)
Ah. Okay. I was predicating my fix on that eventually happening. If we want to explicitly make sure we throw the OOM until then, that's fine.
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.
That's fair. Hmm. I think we should be defensive now, just so we don't end up getting preview bug reports for exceptions that make no sense.
Alternatively, make the managed caller just explicitly throw OOM on -1, and TODO it against #63804
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.
Well, ERR_put_error is deprecated in OpenSSL 3 and it seems silly to use it in an OpenSSL 3-only code path.
<sigh>.
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.
Well, we don't really need to preserve the line. That never appears in the OutOfMemoryException.
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.
Okay, I noticed that we have our own ERR_put_error. I think that is what you're looking for? (ERR_GET_FUNC was removed in OpenSSL 3).
src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c
Outdated
Show resolved
Hide resolved
src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
Outdated
Show resolved
Hide resolved
* Grammar / typos * Order locals and switch cases to be in a consistent order Co-authored-by: Stephen Toub <[email protected]>
|
/backport to release/6.0 |
|
Started backporting to release/6.0: https://github.com/dotnet/runtime/actions/runs/1714595694 |
|
@bartonjs backporting to release/6.0 failed, the patch most likely resulted in conflicts: $ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Applying: Fix OpenSSL 3 reporting an OutOfMemoryException for missing private key.
Using index info to reconstruct a base tree...
M src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
A src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c
A src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.h
Falling back to patching base and 3-way merge...
Auto-merging src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
CONFLICT (content): Merge conflict in src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Fix OpenSSL 3 reporting an OutOfMemoryException for missing private key.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128Please backport manually! |
|
@bartonjs I will manually back port this one. |
Contributes to #63624.
This, with #63655, gives me a green run of S.S.Cryptography in Fedora Rawhide with OpenSSL 3.