This repository has been archived by the owner on Apr 22, 2023. It is now read-only.
crypto: Fix "leak" in SecureContext::SetCert() #5465
Closed
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.
Node.js borrows a function
SSL_CTX_use_certificate_chain
from OpenSSL which handles loading of the certificate bundle provided from a buffer object. However, it looks like the code taken from OpenSSL was originally hanging onto the certificate resource created by SSL_CTX_use_certificate, but it does not seem to be used by Node.js, and not freeing it causes a large amount of memory to be generated and lost (though eventually partially returned in a full GC run). I'm not sure if this is necessarily a "memory leak", but at the very least it is causing less-than-efficient memory usage. The patch frees the resource creating a much more stable memory usage footprint.In order to illustrate the "leak" I wrote a minimal reproduction case listed below which causes system memory usage to skyrocket when creating crypto credentials. Note that SetCert() is exposed through
crypto.createCredentials()
, but for clarity, this minimal test case shows the actual code path within createCredentials() that causes the "leak":To clarify, the leak is only caused when
crypto.createCredentials()
is called with thecert
option filled, which causes it to callSecureContext.setCert()
. Without this, the memory usage looks normal.The following graphs show memory usage when running the above script before and after applying the patch in this pull request:
(Note: these graphs are on a logarithmic scale)
Before patch:
After patch:
I also stress tested this implementation to ensure that freeing memory in the implementation does not cause any segfault/side effects-- I cannot guarantee that this will not cause a segfault, but in my experimentation, it did not cause any. Please try this out on your machines and verify my patch! :)
Finally, my pull request applies this patch on master, but given that it is a backwards compatible change, I believe that it can (and probably should) be backported, since the current behaviour can cause critically poor memory performance.