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

src: add mutex to ManagedEVPPKey class #36825

Closed
wants to merge 1 commit into from

Conversation

danbev
Copy link
Contributor

@danbev danbev commented Jan 7, 2021

This commit introduces a mutex field on the ManagedEVPPKey class
intended to be used when multiple threads require access to an OpenSSL
EVP_PKEY object. The motivation for this came from the work being done
to upgrade Node.js to OpenSSL 3.0.

OpenSSL objects, like EVP_PKEY, are not thread safe (see refs for
details). In versions prior to OpenSSL 3.0 this was not noticeable and
did not cause any issues (like incorrect logic or crashes), but with
OpenSSL 3.0 this does cause issues if access to an EVP_PKEY instance is
required from multiple threads without locking.

In OpenSSL 3.0 when the evp_pkey_downgrade function is called, which
downgrades an EVP_PKEY instance to a legacy version, it will clear all
the fields of EVP_PKEY struct except the lock (#13374). But this also
means that keymgmt and keydata will also be cleared, which other parts
of the code base depends on, and those calls will either fail to export
the key (returning null) or crash due to a segment fault.

This same code works with OpenSSL 1.1.1 without locking and I think this
is because there is no downgrade being done in OpenSSL 1.1.1. But even
so, as far as I can tell there are no guarantees that these object are
thread safe in 1.1.1 either and should be protected with a lock.

Refs:
openssl/openssl#13374
openssl/openssl#2165)
https://www.openssl.org/blog/blog/2017/02/21/threads

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Jan 7, 2021
@nodejs-github-bot
Copy link
Collaborator

@danbev danbev marked this pull request as ready for review January 8, 2021 17:25
@nodejs-github-bot
Copy link
Collaborator

@danbev
Copy link
Contributor Author

danbev commented Jan 11, 2021

Re-run of failing node-test-commit-freebsd/ ✔️

@aduh95
Copy link
Contributor

aduh95 commented Jan 18, 2021

@danbev This needs a rebase.

@danbev danbev force-pushed the crypto-evp-pkey-locking branch from 5da4dee to ed1ae66 Compare January 21, 2021 05:16
@nodejs-github-bot
Copy link
Collaborator

This commit introduces a mutex field on the ManagedEVPPKey class
intended to be used when multiple threads require access to an OpenSSL
EVP_PKEY object. The motivation for this came from the work being done
to upgrade Node.js to OpenSSL 3.0.

OpenSSL objects, like EVP_PKEY, are not thread safe (see refs for
details). In versions prior to OpenSSL 3.0 this was not noticeable and
did not cause any issues (like incorrect logic or crashes), but with
OpenSSL 3.0 this does cause issues if access to an EVP_PKEY instance is
required from multiple threads without locking.

In OpenSSL 3.0 when the evp_pkey_downgrade function is called, which
downgrades an EVP_PKEY instance to a legacy version, it will clear all
the fields of EVP_PKEY struct except the lock (nodejs#13374). But this also
means that keymgmt and keydata will also be cleared, which other parts
of the code base depends on, and those calls will either fail to export
the key (returning null) or crash due to a segment fault.

This same code works with OpenSSL 1.1.1 without locking and I think this
is because there is no downgrade being done in OpenSSL 1.1.1. But even
so, as far as I can tell there are no guarantees that these object are
thread safe in 1.1.1 either and should be protected with a lock.

Refs:
openssl/openssl#13374
openssl/openssl#2165)
https://www.openssl.org/blog/blog/2017/02/21/threads
@danbev danbev force-pushed the crypto-evp-pkey-locking branch from ed1ae66 to c675689 Compare February 9, 2021 13:23
@nodejs-github-bot
Copy link
Collaborator

@danbev
Copy link
Contributor Author

danbev commented Feb 10, 2021

Re-run of failing node-test-commit-linuxone ✔️

@danbev
Copy link
Contributor Author

danbev commented Feb 10, 2021

Landed in 79d44ba.

@danbev danbev closed this Feb 10, 2021
@danbev danbev deleted the crypto-evp-pkey-locking branch February 10, 2021 07:04
danbev added a commit that referenced this pull request Feb 10, 2021
This commit introduces a mutex field on the ManagedEVPPKey class
intended to be used when multiple threads require access to an OpenSSL
EVP_PKEY object. The motivation for this came from the work being done
to upgrade Node.js to OpenSSL 3.0.

OpenSSL objects, like EVP_PKEY, are not thread safe (see refs for
details). In versions prior to OpenSSL 3.0 this was not noticeable and
did not cause any issues (like incorrect logic or crashes), but with
OpenSSL 3.0 this does cause issues if access to an EVP_PKEY instance is
required from multiple threads without locking.

In OpenSSL 3.0 when the evp_pkey_downgrade function is called, which
downgrades an EVP_PKEY instance to a legacy version, it will clear all
the fields of EVP_PKEY struct except the lock (#13374). But this also
means that keymgmt and keydata will also be cleared, which other parts
of the code base depends on, and those calls will either fail to export
the key (returning null) or crash due to a segment fault.

This same code works with OpenSSL 1.1.1 without locking and I think this
is because there is no downgrade being done in OpenSSL 1.1.1. But even
so, as far as I can tell there are no guarantees that these object are
thread safe in 1.1.1 either and should be protected with a lock.

PR-URL: #36825
Refs: openssl/openssl#13374
Refs: openssl/openssl#13374
Refs: openssl/openssl#2165)
Refs: https://www.openssl.org/blog/blog/2017/02/21/threads
Reviewed-By: James M Snell <jasnell@gmail.com>
danielleadams pushed a commit that referenced this pull request Feb 16, 2021
This commit introduces a mutex field on the ManagedEVPPKey class
intended to be used when multiple threads require access to an OpenSSL
EVP_PKEY object. The motivation for this came from the work being done
to upgrade Node.js to OpenSSL 3.0.

OpenSSL objects, like EVP_PKEY, are not thread safe (see refs for
details). In versions prior to OpenSSL 3.0 this was not noticeable and
did not cause any issues (like incorrect logic or crashes), but with
OpenSSL 3.0 this does cause issues if access to an EVP_PKEY instance is
required from multiple threads without locking.

In OpenSSL 3.0 when the evp_pkey_downgrade function is called, which
downgrades an EVP_PKEY instance to a legacy version, it will clear all
the fields of EVP_PKEY struct except the lock (#13374). But this also
means that keymgmt and keydata will also be cleared, which other parts
of the code base depends on, and those calls will either fail to export
the key (returning null) or crash due to a segment fault.

This same code works with OpenSSL 1.1.1 without locking and I think this
is because there is no downgrade being done in OpenSSL 1.1.1. But even
so, as far as I can tell there are no guarantees that these object are
thread safe in 1.1.1 either and should be protected with a lock.

PR-URL: #36825
Refs: openssl/openssl#13374
Refs: openssl/openssl#13374
Refs: openssl/openssl#2165)
Refs: https://www.openssl.org/blog/blog/2017/02/21/threads
Reviewed-By: James M Snell <jasnell@gmail.com>
This was referenced Feb 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants