Repository navigation
Compiling node v4.0.0 with OpenSSL 1.0.1 fails #2783
Copy link
Copy link
Closed
Labels
buildIssues and PRs related to Node.js builds or CI infrastructure.Issues and PRs related to Node.js builds or CI infrastructure.opensslIssues and PRs related to the OpenSSL dependency.Issues and PRs related to the OpenSSL dependency.
Description
We are trying to dynamically link OpenSSL with nodejs. We've done this with previous versions of the v0.12.x with no problems. With v4.0.0 we get a very long compilation error:
$ ./configure --shared-openssl
$ make
# ...
g++ -pthread -rdynamic -m64 -o /tmp/node-v4.0.0/out/Release/cctest -Wl,--start-group /tmp/node-v4.0.0/out/Release/obj.target/cctest/test/cctest/util.o /tmp/node-v4.0.0/out/Release/obj.target/deps/gtest/libgtest.a /tmp/node-v4.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_libplatform.a /tmp/node-v4.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_base.a /tmp/node-v4.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_libbase.a /tmp/node-v4.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_nosnapshot.a -Wl,--end-group -lssl -lcrypto -ldl -lrt
../src/node_crypto.cc: In function 'int node::crypto::SSL_CTX_use_certificate_chain(SSL_CTX*, BIO*, X509**, X509**)':
../src/node_crypto.cc:556:42: error: 'SSL_CTX_add1_chain_cert' was not declared in this scope
r = SSL_CTX_add1_chain_cert(ctx, ca);
^
../src/node_crypto.cc: In static member function 'static void node::crypto::SSLWrap<Base>::CertCbDone(const v8::FunctionCallbackInfo<v8::Value>&)':
../src/node_crypto.cc:2094:51: error: there are no arguments to 'SSL_CTX_get0_certificate' that depend on a template parameter, so a declaration of 'SSL_CTX_get0_certificate' must be available [-fpermissive]
X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
^
../src/node_crypto.cc:2094:51: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
../src/node_crypto.cc:2095:54: error: there are no arguments to 'SSL_CTX_get0_privatekey' that depend on a template parameter, so a declaration of 'SSL_CTX_get0_privatekey' must be available [-fpermissive]
EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
^
../src/node_crypto.cc:2098:51: error: there are no arguments to 'SSL_CTX_get0_chain_certs' that depend on a template parameter, so a declaration of 'SSL_CTX_get0_chain_certs' must be available [-fpermissive]
rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
^
../src/node_crypto.cc: In function 'int node::crypto::VerifyCallback(int, X509_STORE_CTX*)':
../src/node_crypto.cc:2423:24: error: 'SSL_is_server' was not declared in this scope
if (SSL_is_server(ssl))
^
../src/node_crypto.cc: In static member function 'static void node::crypto::Connection::New(const v8::FunctionCallbackInfo<v8::Value>&)':
../src/node_crypto.cc:2505:73: error: 'SSL_set_cert_cb' was not declared in this scope
SSL_set_cert_cb(conn->ssl_, SSLWrap<Connection>::SSLCertCallback, conn);
^
../src/node_crypto.cc: In instantiation of 'static void node::crypto::SSLWrap<Base>::CertCbDone(const v8::FunctionCallbackInfo<v8::Value>&) [with Base = node::TLSWrap]':
../src/node_crypto.cc:135:16: required from here
../src/node_crypto.cc:2094:51: error: 'SSL_CTX_get0_certificate' was not declared in this scope
X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
^
../src/node_crypto.cc:2095:54: error: 'SSL_CTX_get0_privatekey' was not declared in this scope
EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
^
../src/node_crypto.cc:2098:51: error: 'SSL_CTX_get0_chain_certs' was not declared in this scope
rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
^
../src/node_crypto.cc:2104:41: error: 'SSL_set1_chain' was not declared in this scope
rv = SSL_set1_chain(w->ssl_, chain);
^
../src/node_crypto.cc: In instantiation of 'static void node::crypto::SSLWrap<Base>::CertCbDone(const v8::FunctionCallbackInfo<v8::Value>&) [with Base = node::crypto::Connection]':
../src/node_crypto.cc:1129:3: required from 'static void node::crypto::SSLWrap<Base>::AddMethods(node::Environment*, v8::Local<v8::FunctionTemplate>) [with Base = node::crypto::Connection]'
../src/node_crypto.cc:2335:24: required from here
../src/node_crypto.cc:2094:51: error: 'SSL_CTX_get0_certificate' was not declared in this scope
X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
^
../src/node_crypto.cc:2095:54: error: 'SSL_CTX_get0_privatekey' was not declared in this scope
EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
^
../src/node_crypto.cc:2098:51: error: 'SSL_CTX_get0_chain_certs' was not declared in this scope
rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
^
../src/node_crypto.cc:2104:41: error: 'SSL_set1_chain' was not declared in this scope
rv = SSL_set1_chain(w->ssl_, chain);
^
../src/tls_wrap.cc: In member function 'void node::TLSWrap::InitSSL()':
../src/tls_wrap.cc:145:64: error: 'SSL_set_cert_cb' was not declared in this scope
SSL_set_cert_cb(ssl_, SSLWrap<TLSWrap>::SSLCertCallback, this);
^
make[1]: *** [/tmp/node-v4.0.0/out/Release/obj.target/node/src/node_crypto.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: *** [/tmp/node-v4.0.0/out/Release/obj.target/node/src/tls_wrap.o] Error 1
make[1]: Leaving directory `/tmp/node-v4.0.0/out'
make: *** [node] Error 2
To recreate this problem, we happen to have a docker image (cloudfoundry/cflinuxfs2) we are compiling against.
Versions:
- OpenSSL 1.0.1f 6 Jan 2014
- GCC 4.8.2
System Information:
$ cat /etc/lsb-release
at /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
buildIssues and PRs related to Node.js builds or CI infrastructure.Issues and PRs related to Node.js builds or CI infrastructure.opensslIssues and PRs related to the OpenSSL dependency.Issues and PRs related to the OpenSSL dependency.
Activity
christo4ferris commentedon Sep 9, 2015
Hey, @jasnell can you please help with this question/issue? Thanks!
bnoordhuis commentedon Sep 9, 2015
Your copy of openssl is too old, you need 1.0.2.
jbergstroem commentedon Sep 10, 2015
As a guideline, look in
deps/and make sure you have the same version (or newer) if you want to build a against shared libraries.jbergstroem commentedon Sep 10, 2015
Closing. If you're having problems compiling against a newer version of OpenSSL (or the bundled one) feel free to reopen.
flavorjones commentedon Sep 10, 2015
I won't argue with closing this ticket, but for posterity I'd like to state the underlying issue we're trying to solve ...
Node is, for historical reasons, statically linking in openssl. When openssl CVE fixes are announced, it's at best inconvenient and at worst dangerous to have to wait for the node team to ship a new version of Node that bumps openssl. It's better from a "patchability" perspective to be able to dynamically link against the version of openssl that's shipped with, and updated by, the user's linux distro.
For previous versions of Node, people are able to ship a "patchable" version of Node by building their own binary and dynamically linking against openssl.
In Node 4, this ability is still present, which is theoretically all someone would need to ship a patchable Node binary. However, the reality of the situation is that the most common linux distros (including Ubuntu 14.04 LTS) is still shipping with openssl 1.0.1f.
So however old 1.0.1.f is perceived to be, it's still likely the most common version of openssl in the wild, and thus the result of requiring 1.0.2 is that the vast majority of developers/operators are not easily able to build a patchable version of Node.
This hurdle is likely to slow adoption of Node 4, especially among people who are security-minded (at least from my perspective).
Thanks for reading.
MarkKropf commentedon Sep 10, 2015
It should be noted that this is not just a Ubuntu thing. The following commonly used distros are all 1.0.1 based.
RHEL 7.1 - 1.0.1e
Ubuntu 14.04 - 1.0.1f
Fedora 22 - 1.0.1k
Amazon Linux - 1.0.1e
Not sure what value the node community is getting from being put in the critical path for all openssl cve's.
bnoordhuis commentedon Sep 10, 2015
@MarkKropf Putting the loaded language aside, the reason for 1.0.2 is pretty simple: upstream support. From https://www.openssl.org/policies/releasestrat.html:
The LTS version of node v4 will be supported until mid 2018. If we'd stuck with openssl 1.0.1, we'd have a year-and-a-half support gap.
jasnell commentedon Sep 11, 2015
I would disagree that statically linking 1.0.2 into Node is going to impact it's adoption. I understand the concern about managing updates, but the Node.js project in general has been very good overall at getting security updates out. The overlapping LTS plans for OpenSSL and Node.js v4.0.0 are a key concern here as @bnoordhuis points out. Keeping v4.0.0 at v1.0.1 just is not going to be practical given the gap that would exist.
flavorjones commentedon Sep 11, 2015
@jasnell Thanks for weighing in. I respectfully disagree with the characterization of OpenSSL turnaround as "very good", although my experience has been limited.
When openssl 1.0.1m came out, it took nearly four days for v0.10.38 and v0.12.1 to be released. You can read nodejs/node-v0.x-archive#9433 for the timeline on this CVE response.
To be honest, enterprise security teams will expect Node CVE responses at the same time they receive Ubuntu or RHEL security notices, and that's probably not a fair expectation to set on a downstream opensource project.
[-]Compiling node v4.0.0 with `./configure --shared-openssl` fails.[/-][+]Compiling node v4.0.0 with OpenSSL 1.0.1 fails[/+]rvagg commentedon Sep 12, 2015
comparisons to v0.10 and v0.12 releases aren't so helpful here, you're basically talking to an entirely new team managing releases now with completely new processes for shipping
jasnell commentedon Sep 12, 2015
At this point, dropping back to 1.0.1 is not going to be an option in v4.x.
Dynamic linking against v1.0.2 should still be possible, however.
On Sep 11, 2015 5:19 PM, "Rod Vagg" notifications@github.com wrote:
23 remaining items
bnoordhuis commentedon May 2, 2016
I'm going to close out this issue. There hasn't been any activity in the last six months so I'm assuming this is either resolved, obsolete or it wasn't that important after all. It's quite possibly the latter because no one followed up with pull requests, as far as I'm aware.
flavorjones commentedon May 2, 2016
@bnoordhuis That's an unfair assumption to make. It was made pretty clear to us via personal communications that PRs wouldn't be accepted, as there was no consensus that this support was desirable. And that's fine, we dealt with the community decision and moved on with our lives.
You could have just left it at "There hasn't been any activity."
jasnell commentedon May 2, 2016
@flavorjones ... sorry for the confusion.
cschug commentedon May 11, 2016
Would be great to drop a note in
BUILDING.mdregarding version requirements on optional system software components like OpenSSL.jbergstroem commentedon May 12, 2016
@cshug: the optional shared dependencies follows the same versions you can find in
deps/. Just have a look in that folder for your corresponding release!jelmd commentedon Aug 3, 2016
FWIW: patch update wrt 6.x - http://iks.cs.ovgu.de/~elkner/tmp/node6/
UnitedMarsupials-zz commentedon Jan 5, 2017
@jelmd, thank you for posting the link to patches, which allow NodeJS to build against older OpenSSL. Unfortunately, node-7.4.0, when built this way, crashes in many different self-tests... Any chance for an update? More specifically, the crashes all appear to be due to the following double-free:
@bnoordhuis, that may be a reason to use 1.0.2, but it is not a reason to abandon compatibility with the older release and use API-calls absent in 1.0.1. In addition to the already substantial list of Linux-distributions, which still bundle OpenSSL-1.0.1, add FreeBSD... The shared OpenSSL mode of compilation should be the default, and it should be possible to use version 1.0.1 of it (even if that would sacrifice some functionality).
gibfahn commentedon Jan 7, 2017
@UnitedMarsupials isn't 1.0.1 out of support (https://www.openssl.org/policies/releasestrat.html)? If so linking to something that no longer gets security fixes is perhaps not a good idea.
flavorjones commentedon Jan 7, 2017
@gibfahn Ubuntu Trusty 14.04 ships with openssl 1.0.1f, which will be supported by Canonical until April 2019. Canonical will presumably backport security fixes to 1.0.1 until then.
So, while it may be out of support from an upstream perspective, it seems as though some distros are taking on the support responsibility.
UnitedMarsupials-zz commentedon Jan 7, 2017
@gibfahn, whether it is supported by the OpenSSL team (as much as such support even matters in open source), is irrelevant. What is relevant is that the majority of the mainstream operating systems' current versions still include the older version. RedHat/CentOS-7, FreeBSD-10 to name two.
Now, statically linking with OpenSSL is not only wasteful (of both diskspace and run-time RAM -- the most precious resource), but also less secure. To fix a future bug, updating my OpenSSL libraries will not be enough, I'll need to update node separately.
As long as OpenSSL-1.0.1 remains in wide use, applications using the API should be able to use the older version,
#ifdef-ing some latest features, if necessary.I, once again, urge node-developers to switch to using the already-installed versions of all of the
deps/libraries by default and even stop bundling your own versions of them. You aren't as bad as OpenOffice -- which includes its own copy of Python (!) and an entire kitchen-sink of other 3rd-party libraries -- but you are close...jelmd commentedon Jan 7, 2017
@UnitedMarsupials "Unfortunately" ;-) my primary target (Solaris 11) ships openssl 1.0.2 since 11.3 SRU 14.6 (November 2016) and thus there is no need => no time to maintain the 1.0.2 related patches (i.e. ssl*.patch). Never tested any version < 5.0.0 || > 6.3.1 with it. So yes, it may fail on other versions or not even align with the openssl packages shipped by your OS vendor. E.g. I know, that RedHat often ports back features of "next releases" and thus the system/openssl util might say it is 1.0.1, but already provides features from 1.0.2 (e.g.
SSL_get_server_tmp_key()). Perhaps Canonical or other vendors do similar things. In this case it is probably the best to check the vendor patches for the related packages/do areadelf -s $liband if it looks promising, adjust the node build system to accept 1.0.1 (not sure, if there is an explicit version number check) and try, how far it goes ...So FWIW: My patch set for 6.9.1 got reduced to http://iks.cs.ovgu.de/~elkner/tmp/node6-1.0.2/
And yes - I agree, static linking is evil for several reasons, but on the other side a "quick and dirty" workaround/"promotion help" as long as OS distributions haven't caught up (even the latest Ubuntu still ships 0.12?) ...
gibfahn commentedon Jan 7, 2017
@jelmd Ubuntu 16.04 is
v4.2.6for me.jelmd commentedon Jan 7, 2017
Ah ok - thanx!
UnitedMarsupials-zz commentedon Jan 8, 2017
@jelmd, yes, the OSes are moving to upgrade their OpenSSL pieces, but slowly -- RedHat, which is what I'm saddled with at work, still has 1.0.1 in their current version 7. FreeBSD -- which is what I use at home -- includes 1.0.2, but only in version 11, which is meant for "early adopters". The mainstream FreeBSD-10 still contains OpenSSL-1.0.1.
Now, my debugging of the double-free posted above shows, that the block being freed is a root certificate store, which is somehow referenced by two different context-structures. Says valgrind:
Could it be, your patches simply forget to up a ref-count somewhere?