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

JsThemis crashes on some Linux systems #657

Open
2 tasks done
ilammy opened this issue Jun 15, 2020 · 1 comment
Open
2 tasks done

JsThemis crashes on some Linux systems #657

ilammy opened this issue Jun 15, 2020 · 1 comment
Labels
bug C-OpenSSL Crypto provider: OpenSSL/LibreSSL core Themis Core written in C, its packages O-Linux 🐧 Operating system: Linux W-JsThemis 🍭 Wrapper: JsThemis for Node.js, JavaScript API, npm packages
Milestone

Comments

@ilammy
Copy link
Collaborator

ilammy commented Jun 15, 2020

Describe the bug
Any call to JsThemis method can cause the node binary to crash with “Segmentation fault” error.

Only some systems with older Node.js binaries are affected. See below for details.

To Reproduce
Steps to reproduce the behavior:

  1. Install JsThemis on a system with affected Node.js.
  2. Use any function.
  3. See the following error:
Segmentation fault (core dumped)

Developers can reproduce the issue by running JsThemis unit tests:

git clone https://github.com/cossacklabs/themis
cd themis/src/wrappers/themis/jsthemis
npm install
npm test
> [email protected] test src/wrappers/themis/jsthemis
> mocha
Segmentation fault (core dumped)
npm ERR! Test failed.  See above for more details.
tests/test.mk:139: recipe for target 'test_js' failed
make: *** [test_js] Error 1

Expected behavior
JsThemis should not crash, regardless of Node.js version and build.

Environment:

  • OS: Linux only, macOS is not affected
    • Reproduced and found on Debian 9
    • System OpenSSL version seems to be defining trait
  • Hardware: i386
    • Does not seem to reproduce for amd64 builds
  • Themis version: all current versions, up to Themis 0.13.0
  • Installation way:
    • via package manager
    • built from source

Node.js versions known to be affected:

Additional context
There is a known workaround. Do not install install Themis Core from Cossack Labs package repositories. Instead, compile and install Themis Core from source, using BoringSSL:

export ENGINE=boringssl
make
sudo make install
@ilammy ilammy added bug core Themis Core written in C, its packages O-Linux 🐧 Operating system: Linux C-OpenSSL Crypto provider: OpenSSL/LibreSSL W-JsThemis 🍭 Wrapper: JsThemis for Node.js, JavaScript API, npm packages labels Jun 15, 2020
@ilammy
Copy link
Collaborator Author

ilammy commented Jun 15, 2020

This issue is caused by duplicate OpenSSL symbols.

Due to the way ELF linkage and loading works on Linux, Themis may be using OpenSSL functions different from the ones it was compiled. ABI mismatches are sometimes unnoticeable, sometimes lead to crashes, and sometimes lead to unexpected behavior.

⚠️ Warning:
Using JsThemis with prebuilt Themis Core packages may be not safe. If you can, please build Themis Core from source for now.

How linkage should work

Normally, JsThemis addon uses Themis Core libraries installed from binary packages hosted by Cossack Labs. We build there packages for various distros, using the OpenSSL package provided by the distro. That way JsThemis gets all security updates in OpenSSL essentially for free, from a package maintained by distro maintainers.

This is how linkage and installation should look in the ideal case:

Ideal scheme

Node.js loads JsThemis, which uses Themis which uses Soter which uses OpenSSL installed into the system.

How it actually works (or doesn't)

Node.js binary includes its own copy of OpenSSL inside it. It has been like this historically, and it is important for some native add-ons which expect OpenSSL to be available with just Node.js.

However, due to way symbol lookup works on Linux, this is what happens:

Buggy scheme

Soter uses OpenSSL functions from the Node.js binary, not the ones from system’s OpenSSL. It is still loaded, but mostly ignored after that.

Sometimes it is fine since OpenSSL does a good job at keeping ABI compatibility. However, if Node.js was built with a different version of OpenSSL than the one installed in the system, then ABI mismatch may happen. Data structures will have different layout, function implementations may be different, etc. This causes undefined behavior, most likely leading to a crash.

Though, if OpenSSL versions in system and Node.js match then JsThemis will kinda work fine.

What we are planning to do

Unfortunately, we can’t change the way linkage works on Linux. And we can’t remove OpenSSL from Node.js. Therefore, we are planning to switch to the following scheme in a future release:

Solution with BoringSSL

By using embedded BoringSSL, Soter will use the library it was built with, avoiding the possibility of symbol clash and ABI mismatch.

This approach is tracked in issue #619.

Alternatives

Another way this issue can be solved is to link Soter against Node.js OpenSSL:

Node.js OpenSSL alternative

This will avoid duplicating cryptographic code in memory (due to OpenSSL and BoringSSL being loaded), but it’s not really practical for us. We’d have to build Themis for each individual Node.js version. Then we’d need to teach the users to install a version of Themis that matches their Node.js installation (or have the users build Themis from source). This is not very convenient, both for us and the users.

Furthermore, using BoringSSL allows us to issue security updates to Themis independently of Node.js security updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug C-OpenSSL Crypto provider: OpenSSL/LibreSSL core Themis Core written in C, its packages O-Linux 🐧 Operating system: Linux W-JsThemis 🍭 Wrapper: JsThemis for Node.js, JavaScript API, npm packages
Projects
None yet
Development

No branches or pull requests

1 participant