Bug 1510641 - rh-nodejs4 encounters a SEGFAULT in SSL_CTX_use_certificate_chain [rhscl-3.1.0]
Summary: rh-nodejs4 encounters a SEGFAULT in SSL_CTX_use_certificate_chain [rhscl-3.1.0]
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Software Collections
Classification: Red Hat
Component: nodejs
Version: rh-nodejs4
Hardware: Unspecified
OS: Unspecified
urgent
high
Target Milestone: alpha
: 3.1
Assignee: Zuzana Svetlikova
QA Contact: Mirek Długosz
URL:
Whiteboard:
Depends On:
Blocks: 1513065
TreeView+ depends on / blocked
 
Reported: 2017-11-07 21:47 UTC by Kyle Walker
Modified: 2021-03-11 16:13 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Prior to this update, the Node.js server was unable to correctly handle certificate chains. As a consequence, the Node.js server terminated unexpectedly with a segmentation fault. This bug has been fixed, and users are now able to authenticate using certificate chains.
Clone Of:
: 1513065 1513067 1589027 (view as bug list)
Environment:
Last Closed: 2017-11-20 14:04:45 UTC
Target Upstream Version:
Embargoed:
zsvetlik: needinfo+


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2017:3249 0 normal SHIPPED_LIVE rh-nodejs4 bug fix update 2017-11-20 19:04:21 UTC

Description Kyle Walker 2017-11-07 21:47:43 UTC
Description of problem:
 When handling a certificate chain, such as multiple certificates in a single PEM encoded file, the following backtrace is observed:

  (gdb) bt
  #0  0x00007f825e5823f0 in asn1_enc_restore (<snip>) at tasn_utl.c:189
  #1  0x00007f825e57f5d3 in ASN1_item_ex_i2d (<snip>) at tasn_enc.c:198
  #2  0x00007f825e57fc79 in asn1_template_ex_i2d (<snip>) at tasn_enc.c:402
  #3  0x00007f825e57f737 in ASN1_item_ex_i2d (<snip>) at tasn_enc.c:225
  #4  0x00007f825e57f93f in asn1_item_flags_i2d (<snip>) at tasn_enc.c:119
  #5  0x00007f825e57f9e7 in ASN1_item_i2d (<snip>) at tasn_enc.c:91
  #6  0x00007f825e57abfc in i2d_X509 (<snip>) at x_x509.c:143
  #7  0x00007f825e8db9dd in ssl_add_cert_to_buf (<snip>) at ssl_cert.c:1059
  #8  0x00007f825e8dd388 in ssl_add_cert_chain (<snip>) at ssl_cert.c:1143
  #9  0x00007f825e8c2135 in ssl3_output_cert_chain (<snip>) at s3_both.c:327
  #10 0x00007f825e8ba944 in ssl3_send_client_certificate (<snip>) at s3_clnt.c:3488
  #11 0x00007f825e8baf7f in ssl3_connect (<snip>) at s3_clnt.c:421
  #12 0x00007f825e8c023e in ssl3_write_bytes (<snip>) at s3_pkt.c:655
  #13 0x0000000000b9ac38 in node::TLSWrap::ClearIn (<snip>) at ../src/tls_wrap.cc:485
  #14 0x0000000000b9b7eb in Cycle (<snip>) at ../src/tls_wrap.h:100
  #15 node::TLSWrap::DoRead (<snip>) at ../src/tls_wrap.cc:728
  #16 0x0000000000b73985 in OnRead (<snip>) at ../src/stream_base.h:169
  #17 node::StreamWrap::OnReadCommon (<snip>) at ../src/stream_wrap.cc:251
  #18 0x00007f825f359954 in uv__read (<snip>) at ../src/unix/stream.c:1178
  #19 0x00007f825f359e8c in uv__stream_io (<snip>) at ../src/unix/stream.c:1241
  #20 0x00007f825f35e436 in uv__io_poll (<snip>) at ../src/unix/linux-core.c:345
  #21 0x00007f825f3520f0 in uv_run (<snip>) at ../src/unix/core.c:341
  #22 0x0000000000b3ccf0 in node::Start (<snip>) at ../src/node.cc:4230
  #23 0x00007f825d872c05 in __libc_start_main (<snip>) at ../csu/libc-start.c:274
  #24 0x0000000000655e59 in _start (<snip>)


Version-Release number of selected component (if applicable):
  rh-nodejs4-nodejs-4.6.2-6.el7
  rh-nodejs6-nodejs-6.11.3-2.el7
  openssl-1.0.2k-8.el7.x86_64

How reproducible:
  Simply

Steps to Reproduce:
1. Generate a client certificate, validity not necessary as the problem is observed in valid use-cases and invalid.

  # # openssl req -x509 -nodes -out client.crt -newkey rsa:4096 -keyout test.key -subj "/CN=Test"
 
2. Duplicate the client certificate

  # cat client.crt client.crt > test.crt

3. Start a nodejs4 https server in the following fashion:

  # cat server.js
  var fs = require('fs');
  var constants = require('constants');
  var https = require('https');
  var httpsPort = 8443;

  var sslOptions = {
    key: fs.readFileSync('./client.key'),
    cert: fs.readFileSync('./test.crt'),
    secureProtocol: 'SSLv23_method',
    secureOptions: constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_SSLv2,
  };

  https.createServer(sslOptions).listen(httpsPort);
  console.log("Listening: "+httpsPort);

  # scl enable rh-nodejs4 -- node server.js

4. Connect to the above via s_client

  # echo "" | openssl s_client -connect localhost:8443

Actual results:

  # scl enable rh-nodejs4 -- node server.js
  Listening: 8443
  /var/tmp/sclIfAGVI: line 8:   773 Segmentation fault      (core dumped) "node" "server.js"

Expected results:
  # scl enable rh-nodejs4 -- node server.js
  Listening: 8443
  <No SEGFAULT>

Additional info:
  This seems to be due to the presence of the *-Disable-openssl.patch and lack of BuildRequires/Requires dependencies within the rh-nodejs4 and rh-nodejs6 RPMs. The rh-nodejs8 package does not include this patch and does not suffer from the same failure.

Comment 2 Kyle Walker 2017-11-07 22:09:17 UTC
Just to elaborate, the end failure is specifically in the following code snippet when a connection is accepted.

ssl_add_cert_chain()
<snip>
1141	    for (i = 0; i < sk_X509_num(extra_certs); i++) {
1142	        x = sk_X509_value(extra_certs, i);
1143	        if (!ssl_add_cert_to_buf(buf, l, x))
1144	            return 0;
1145	    }
<snip>

(gdb) f
#11 0x00007ffff6d329dd in ssl_add_cert_to_buf (buf=buf@entry=0x11e4610, l=l@entry=0x7fffffff7200, x=0x12431f0) at ssl_cert.c:1059
1059	    n = i2d_X509(x, NULL);
(gdb) p *x
$11 = {
  cert_info = 0x7ffff6f5a710 <ssl3_ciphers+10384>, 
  sig_alg = 0x7ffff6f5a5b0 <ssl3_ciphers+10032>, 
  signature = 0x7ffff6f5a768 <ssl3_ciphers+10472>, 
  valid = -151673336, 
  references = 32767, 
  name = 0x7ffff6f596e8 <ssl3_ciphers+6248> "\001", 
  ex_data = {
    sk = 0x7ffff6f5a450 <ssl3_ciphers+9680>, 
    dummy = -151679760
  }, 
  ex_pathlen = 140737336681640, 
  ex_pcpathlen = 140737336675920, 
  ex_flags = 140737336681288, 
  ex_kusage = 140737336680672, 
  ex_xkusage = 140737336679792, 
  ex_nscert = 140737336678736, 
  skid = 0x7ffff6f598a0 <ssl3_ciphers+6688>, 
  akid = 0x7ffff6f597f0 <ssl3_ciphers+6512>, 
  policy_cache = 0x7ffff6f59740 <ssl3_ciphers+6336>, 
  crldp = 0x7ffff6f58df8 <ssl3_ciphers+3960>, 
  altname = 0x7ffff6f58da0 <ssl3_ciphers+3872>, 
  nc = 0x7ffff6f58d48 <ssl3_ciphers+3784>, 
  rfc3779_addr = 0x7ffff6f58820 <ssl3_ciphers+2464>, 
  rfc3779_asid = 0x7ffff6f587c8 <ssl3_ciphers+2376>, 
  sha1_hash = "p\207\365\366\377\177\000\000\030\207\365\366\377\177\000\000\030\250\365\366", 
  aux = 0x7ffff6f5a6b8 <ssl3_ciphers+10296>
}

The upstream node revision does not suffer from the same issue as the openssl libraries are statically linked in and presumed to be a specific version/API. Therefore, they do not need to override the SSL_CTX_use_certificate_chain() behaviour as the indicated *-Disable-openssl.patch does below:

@@ -521,9 +621,20 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
     for (int i = 0; i < sk_X509_num(extra_certs); i++) {
       X509* ca = sk_X509_value(extra_certs, i);

-      // NOTE: Increments reference count on `ca`
-      r = SSL_CTX_add1_chain_cert(ctx, ca);
-
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+       // If ctx->cert->key != NULL create ctx->cert->key->chain if not
+       // already there, push 'ca' to this chain and finally increment the ca
+       // reference count by 1 (this is the diff between *_add1_* and *_add0_*
+       // - the later increments by 0 ;-)) and return 1. Otherwise or if
+       // something fails in between, return 0.
+       r = SSL_CTX_add1_chain_cert(ctx, ca);
+#else
+       // Create ctx->extra_certs if not already there, just push 'ca' to this
+       // chain and return 1. If something fails, return 0.
+       // NOTE: 1.0.1- does not support multiple certs having its own chain in
+       //       a single context. There is just one: extra_chain!
+       r = SSL_CTX_add_extra_chain_cert(ctx, ca);
+#endif
       if (!r) {
         ret = 0;
         *issuer = nullptr;


Kyle Walker
Senior Software Maintenance Engineer - SEG
North America

Comment 17 errata-xmlrpc 2017-11-20 14:04:45 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2017:3249


Note You need to log in before you can comment on or make changes to this bug.