** Description changed:

  [impact]
  
  Pre-built addons for nodejs built against the 8.10 version, which is
  what is included in Bionic, will fail to load on Bionic because the
  version of nodejs there is built using a newer ABI-incompatible openssl
  version.
  
  [test case]
  
  see comment 4 (and discussion in following comments)
  
  [regression potential]
  
- any nodejs addons built for the current version of nodejs in Bionic will
- need to be re-built to pick up the different openssl ABI.  This appears
- to be a rather significant list of packages.  Any external nodejs addons
- that were built specifically for the current Bionic nodejs will also
- start failing, until rebuilt against the upstream nodejs 8.10 version,
- or the new Bionic nodejs package.
+ Although this SRU changes the ABI of nodejs that is exposed to binary
+ add-ons, the practical regression potential for this ABI change is
+ minimal.  The archive has been scanned to confirm there are no reverse-
+ dependencies in Ubuntu which use this part of the ABI, and it is not
+ feasible to build third-party binaries that are compatible with nodejs
+ as shipped in 18.04 because the gyp build system used by the nodejs
+ ecosystem exposes system headers that don't match the symbols exported
+ by the current Ubuntu nodejs built against OpenSSL 1.1.
+ 
+ Thus, the greatest risk of regression is from someone manually working
+ around this gyp incompatibility in order to build an add-on which uses
+ these symbols.  This risk is negligible.
  
  Changing this to use openssl1.0 assumes that the security team will
  maintain security patches for openssl1.0.
+ 
+ There is no risk of regression in protocol compatibility by switching
+ back from openssl 1.1 to openssl 1.0, because TLS 1.3 support has not
+ yet landed in the openssl package in 18.04.
  
  [other info]
  
  alternately, this could be fixed by upgrading the nodejs package in
  Bionic (and Cosmic) to a newer nodejs - Debian has version 10.4.0 in
  experimental.
  
  also debian 904274 has quite a bit of discussion.
  
  original bug description below.
  ---
  
  Background:
  NodeJS has a native extension API: https://nodejs.org/api/addons.html
  It's fairly understood by developers that NodeJS's ABI is stable, and that 
one module built using a version of nodejs should work on another semantically 
version compatible of nodejs.
  
  NodeJS exposes various third party libraries to the native module
  developers. Quote from the addons developers page: "Node.js includes a
  number of other statically linked libraries including OpenSSL. These
  other libraries are located in the deps/ directory in the Node.js source
  tree. Only the libuv,i OpenSSL, V8 and zlib symbols are purposefully re-
  exported by Node.js and may be used to various extents by Addons."
  
  It's fairly understood by developers that native modules have the same
  ABI guarantee than the rest of the node API.
  
  The NodeJS ecosystem uses native modules extensively, and it's fairly
  common for developers to publish precompiled versions of their
  extensions so that the typical end-user can simply npm install their
  dependencies without worrying about having a compiler installed. Some
  packages will do their own thing (see for instance
  https://www.npmjs.com/package/uws), while others will rely on third
  party extensions to facilitate their work. See for instance prebuild
  (https://www.npmjs.com/package/prebuild) that has a handful of
  dependents, or node-pre-gyp (https://www.npmjs.com/package/node-pre-gyp)
  that has north of 350 dependents. So the nodejs ecosystem has roughly
  400 native packages that are publishing prebuilt versions of their
  extensions.
  
  Problem with the Ubuntu nodejs package:
  Put simply, it breaks prebuilt packages that depend on OpenSSL. NodeJS 8.10.0 
officially comes with OpenSSL 1.0.2n, while the NodeJS 8.10.0 that comes with 
the Ubuntu package exposes OpenSSL 1.1.0g.
  
  Since there are ABI breakages between OpenSSL 1.0.2 and 1.1.0, these ABI
  breakages are bubbling up to any prebuilt native addon.
  
  Here is an example:
  
  https://github.com/nicolasnoble/openssl-nodejs-ubuntu-demo
  
  If you build this package under the mainline nodejs, it will try to import 
the following symbols from OpenSSL 1.0.2:
   . SSL_library_init
   . SSLeay_version
  
  Whereas if you build it under Ubuntu's nodejs, it will try to import the 
following symbols instead from OpenSSL 1.1.0:
   . OPENSSL_init_ssl
   . OpenSSL_version
  
  Therefore, trying to load one prebuilt module from one version of the
  runtime to another will result in a symbol loading error:
  
  node: symbol lookup error: /home/pixel/node-openssl-addon-
  example/build/Release/openssl_example.node: undefined symbol:
  SSL_library_init
  
  Incidentally, nodejs 10.5.0 uses OpenSSL 1.1.0h, and compiling the same
  demo module with this version of node will try to import the proper
  symbols. Obviously, since the module will be built for the wrong version
  of the nodejs runtime, it won't load, but the SSL symbols are now
  proper.
  
  This creates weird bug reports for nodejs extension developers, such as
  https://github.com/grpc/grpc-node/issues/341
  
  Another example is uws. Trying to use uws in ubuntu's nodejs will result
  in the same sort of failures. Which means there are at least two
  packages available out there that are affected by this issue.
  
  I don't think this is easily solvable, and all of my suggestions for
  fixing it have severe cons. Ubuntu won't want to downgrade their
  system's OpenSSL for this. Maybe there's a way to get another openssl
  package for 1.0.2, and have the nodejs runtime for Ubuntu depend on it.
  Another possible solution would be to radically upgrade nodejs to 10, so
  that the ABI of OpenSSL will then match properly. But this may be viewed
  as a too radical upgrade.
  
  One sort of mitigation option would be to get node-pre-gyp and prebuild
  to recognize that it's running with this version of the nodejs runtime,
  so that it can recognize and take actions, such as downloading an
  ubuntu-specific version of the prebuilt extension, or recompiling from
  sources. This obviously would help mitigating the issue for a good
  portion of existing packages that are using node-pre-gyp and prebuild,
  but for packages that are doing their own thing such as uws, this
  solution wouldn't work properly.
  
  ProblemType: Bug
  DistroRelease: Ubuntu 18.04
  Package: nodejs 8.10.0~dfsg-2
  ProcVersionSignature: Ubuntu 4.15.0-24.26-generic 4.15.18
  Uname: Linux 4.15.0-24-generic x86_64
  ApportVersion: 2.20.9-0ubuntu7.2
  Architecture: amd64
  CurrentDesktop: ubuntu:GNOME
  Date: Tue Jul  3 05:34:28 2018
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2017-03-08 (482 days ago)
  InstallationMedia: Ubuntu 16.10 "Yakkety Yak" - Release amd64 (20161012.2)
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=<set>
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  SourcePackage: nodejs
  UpgradeStatus: Upgraded to bionic on 2018-05-10 (54 days ago)

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1779863

Title:
  Ubuntu nodejs package isn't ABI compatible with mainline nodejs.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/nodejs/+bug/1779863/+subscriptions

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to