Closed JCMais closed 2 years ago
This is directly related to this issue: https://github.com/nodejs/node/issues/24964
Bumping this, I still have not found a correct solution to that issue, and I'm still looking into one
This is still an issue. Just found another problem:
Let's imagine that an addon dependency (shared library, in my case it's libcurl/libssh) was built with OpenSSL 1.1.x (static linked in this case), when running the addon, that dependency will receive the OpenSSL version Node.js exports, instead of the one it was built with.
And so by building this addon against Node.js v8, which is built with OpenSSL 1.0.x, it will end in a segmentation fault.
@JCMais - trying to understand the issue better: is the requirement to be able to build a native addon that links against system supplied openssl, while node itself was built with resident openssl?
hey @gireeshpunathil, basically yes.
The requirement is to build a native addon using their own version of OpenSSL, which can differ from the one used by Node.js itself.
My use case was building an addon that depends on libcurl, which in turn depends on OpenSSL.
thanks @JCMais for the clarification.
I guess it is not going to be feasible? As any standard SSL implementations should export the public interfaces, the executing code (node app + native addon) at run time face symbol resolution conflicts between the two, and depend on the prevalent linker flags etc. this conflict is going to manifest in different manner.
if your requirement is to build a native addon using their own version of OpenSSL without strict requirement on the one used by Node.js itself, then you can build Node.js from source with --shared-openssl
, --shared-openssl-includes
, --shared-openssl-libname
and --shared-openssl-libpath
passed to the configure
where the custom library is the same that will be used by the native addon I guess.
pinging @sam-github to see if my understanding is correct.
most OS's provide runtime linking option that helps overriding symbols that can be used as a hack here, but its reliability is questionable - the app that has started with the in-built routines and assuming a specific program state, will be switched to another set of routines when the addon is loaded - can cause unpredictable results IMO.
@JCMais I don't know if I can help you here.
An addon is dynamically loaded into node.js. In a sense, it becomes PART of the node.js executable. It is not easy for executables written in C/C++ to depend on two different versions of a single library. This isn't node specific, and may be flat out impossible, which may be why you aren't finding any solution.
That said, I believe that this may be possible if your addon:
But full disclosure, I haven't tried, so YMMV.
If we can step back a bit, I might be able to help if you described why you are trying to do this. What is it you are trying to do that led to this attempt to use two versions of OpenSSL simultaneously? Gireesh's suggestion to build a custom node so your addon and node share the same openssl seems very possible, though still begs the question "what is it you are trying to do".
@sam-github Take a read on the linked issue https://github.com/nodejs/node/issues/24964 It answers your questions as to why what you suggest won't work.
TLDR; Even if you statically link openssl into your add-on, when the add-on is loaded into Node if there are symbols that are the same between openssl versions and happen to be in the Node process, they get used over what was linked in the add-on. It gets even worse when your add-on relies on 3rd party libraries that use openssl (see discussion of curl).
The prebuilt node distributions basically have created this mess by statically linking to a version of openssl that is not standard in the target OS for the prebuilt distributions.
Got it. Moving conversation to #24964
Hi,
I’m facing a very very similar issue, but on Linux with HMAC code. @hsgreen have you found a way to prevent that node overriding? I’m statically linking a C++ library to some OpenSSL 1.0.1e that gets loaded by the node app.
I solved a similar issue by building node.js manually from source with
./configure --shared-openssl --shared-openssl-includes=/usr/include/ --shared-openssl-libpath=/usr/lib/x86_64-linux-gnu/
I guess if you also do this against the same version that your C++ code uses, it will work.
I solved a similar issue by building node.js manually from source with
./configure --shared-openssl --shared-openssl-includes=/usr/include/ --shared-openssl-libpath=/usr/lib/x86_64-linux-gnu/
I guess if you also do this against the same version that your C++ code uses, it will work.
This works but if you are building an Node.js addon to be installed via NPM it's not feasible.
At the end of the day what worked was to always use the exact OpenSSL version used on Node.js while building the addon. From what I could see this still creates duplicate symbols on the final binary, but atleast there is no ABI conflict.
As I'm building prebuilt binaries for the addon, the binaries must use the same OpenSSL version than the one used by the Node.js version they are targetting. If the user is installing the package building from source they must have a libcurl built with the same OpenSSL version than the one used by their current Node.js version, I made this clear in the README.md of the project, but this is not that great since most people do not read that before installing a package.
@phaazon , were you able to follow @peschue' s suugestion? is it still an pending?
This is a serious issue and it just DOESNT work. There are at least 2 libraries where it's present.
Try an EL7 with rh-nodejs12
from SCL, you'll see what happens. SCL team did a great job of not going nuts and actually doing the sane thing -- which is linking against shared OS supplied openssl lib. Why would you bundle your own version of openssl guys? What happens if there's a secvuln in this bundled lib, and I guess your willingness to go that far means there are tons of these libs, who's gonna cover it? There are lots of examples when such software isn't updated (e.g., 3 years from now for node 12, you/SCL will stop updating it) while OS is still on extended maintenance -- and would get sec fixes, including openssl sec patches.
You should've gotten someone from "big 3" on your team, centos, ubuntu, oracle, suse, those guys, who really know their shit, not some amateur students.
Alright, circling back on this. 1) has been resolved by repo authors and 2) seems to have some kind of configuration problem.
Nevertheless, my complaint is still valid. The proper and ultimate fix is an easy one --- just don't supply any openssl code when nodejs has been compiled with shared openssl. This is how I worked around problem in 2):
rm -rf ~/.cache/node-gyp/12.18.2/include/node/openssl
in the middle of compilation, then restarting the compile again. This wouldn't have been needed if node-gyp hadn't been pulling openssl stuff for some unknown reason.
I've opened a similar issue on node-gyp (https://github.com/nodejs/node-gyp/issues/1559), and there are more information there, but since there was no solution posted, I'm also opening another issue here to have more chances of a definitive solution / guide.
Currently building a native addon with a version of OpenSSL independent of the one shipped with Node.js is very hard, at least to me with basic knowledge on linking / libraries in C++ and / or using gyp files.
Looks like the shipped symbols always take precedence, no matter what I do, which causes all kinds of weird errors and segmentation faults.
There are many other issues about this topic, most are closed without a real solution, and the following wiki page is outdated: https://github.com/nodejs/node-gyp/wiki/Linking-to-OpenSSL