From 6d3aaa72a8c29b134fc2aaead8f2973b619741c4 Mon Sep 17 00:00:00 2001 From: Mariusz 'koder' Chwalba Date: Tue, 27 Sep 2016 08:20:10 +0200 Subject: [PATCH 01/15] tls: TLSSocket emits 'error' on handshake failure Removes branch that would make TLSSocket emit '_tlsError' event if error occured on handshake and control was not released, as it was never happening. Added test for tls.Server to ensure it still emits 'tlsClientError' as expected. Note that 'tlsClientError' does not exist in the v4.x branch so this back-port emits 'clientError' instead. See also pull request #4557. Fixes: https://github.com/nodejs/node/issues/8803 PR-URL: https://github.com/nodejs/node/pull/8805 Refs: https://github.com/nodejs/node/pull/4557 Reviewed-By: Matteo Collina Reviewed-By: Fedor Indutny --- lib/_tls_wrap.js | 4 +- ...rver-failed-handshake-emits-clienterror.js | 36 ++++++++++++++++++ ...tls-socket-failed-handshake-emits-error.js | 38 +++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-tls-server-failed-handshake-emits-clienterror.js create mode 100644 test/parallel/test-tls-socket-failed-handshake-emits-error.js diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index cb435e45f26ef6..31cbe3e65edfa9 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -463,7 +463,9 @@ TLSSocket.prototype._init = function(socket, wrap) { // Destroy socket if error happened before handshake's finish if (!self._secureEstablished) { - self.destroy(self._tlsError(err)); + // When handshake fails control is not yet released, + // so self._tlsError will return null instead of actual error + self.destroy(err); } else if (options.isServer && rejectUnauthorized && /peer did not return a certificate/.test(err.message)) { diff --git a/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js b/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js new file mode 100644 index 00000000000000..a02912542221fb --- /dev/null +++ b/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js @@ -0,0 +1,36 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} +const tls = require('tls'); +const net = require('net'); +const assert = require('assert'); + +const bonkers = Buffer.alloc(1024, 42); + +let clientErrorEmited = false; + +const server = tls.createServer({}) + .listen(0, function() { + const c = net.connect({ port: this.address().port }, function() { + c.write(bonkers); + }); + + }).on('clientError', function(e) { + clientErrorEmited = true; + assert.ok(e instanceof Error, + 'Instance of Error should be passed to error handler'); + assert.ok(e.message.match( + /SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol/), + 'Expecting SSL unknown protocol'); + }); + +setTimeout(function() { + server.close(); + + assert.ok(clientErrorEmited, 'clientError should be emited'); + +}, common.platformTimeout(200)); diff --git a/test/parallel/test-tls-socket-failed-handshake-emits-error.js b/test/parallel/test-tls-socket-failed-handshake-emits-error.js new file mode 100644 index 00000000000000..f655dc97b5a99b --- /dev/null +++ b/test/parallel/test-tls-socket-failed-handshake-emits-error.js @@ -0,0 +1,38 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} +const tls = require('tls'); +const net = require('net'); +const assert = require('assert'); + +const bonkers = Buffer.alloc(1024, 42); + +const server = net.createServer(function(c) { + setTimeout(function() { + const s = new tls.TLSSocket(c, { + isServer: true, + server: server + }); + + s.on('error', common.mustCall(function(e) { + assert.ok(e instanceof Error, + 'Instance of Error should be passed to error handler'); + assert.ok(e.message.match( + /SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol/), + 'Expecting SSL unknown protocol'); + })); + + s.on('close', function() { + server.close(); + s.destroy(); + }); + }, common.platformTimeout(200)); +}).listen(0, function() { + const c = net.connect({port: this.address().port}, function() { + c.write(bonkers); + }); +}); From 07b92a3c0b4f3c2ae947b86723394480c52dfd29 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Fri, 17 Mar 2017 17:34:54 -0400 Subject: [PATCH 02/15] doc: add supported platforms list for v4.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/12091 Reviewed-By: James M Snell Reviewed-By: JoãReis Reviewed-By: Johan Bergströbugs@bergstroem.nu> --- BUILDING.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++---- README.md | 2 +- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 667714ba2b3de5..57f790be8ba042 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -8,21 +8,76 @@ If you consistently can reproduce a test failure, search for it in the [Node.js issue tracker](https://github.com/nodejs/node/issues) or file a new issue. +## Supported platforms + +This list of supported platforms is current as of the branch / release to +which it is attached. + +### Input + +Node.js relies on V8 and libuv. Therefore, we adopt a subset of their +supported platforms. + +### Strategy + +Support is divided into three tiers: + +* **Tier 1**: Full test coverage and maintenance by the Node.js core team and + the broader community. +* **Tier 2**: Full test coverage but more limited maintenance, + often provided by the vendor of the platform. +* **Experimental**: Known to compile but not necessarily reliably or with + a full passing test suite. These are often working to be promoted to Tier + 2 but are not quite ready. There is at least one individual actively + providing maintenance and the team is striving to broaden quality and + reliability of support. + +### Supported platforms + +| System | Support type | Version | Architectures | Notes | +|--------------|--------------|----------------------------------|----------------------|------------------| +| GNU/Linux | Tier 1 | kernel >= 2.6.18, glibc >= 2.5 | x86, x64, arm, arm64 | | +| macOS | Tier 1 | >= 10.10 | x64 | | +| Windows | Tier 1 | >= Windows 7 or >= Windows2008R2 | x86, x64 | | +| SmartOS | Tier 2 | >= 14 | x86, x64 | | +| FreeBSD | Tier 2 | >= 10 | x64 | | +| GNU/Linux | Tier 2 | kernel >= 4.2.0, glibc >= 2.19 | ppc64be | | +| GNU/Linux | Tier 2 | kernel >= 3.13.0, glibc >= 2.19 | ppc64le | | +| macOS | Experimental | >= 10.8 < 10.10 | x64 | no test coverage | +| Linux (musl) | Experimental | musl >= 1.0 | x64 | | + + +### Supported toolchains + +Depending on host platform, the selection of toolchains may vary. + +#### Unix + +* GCC 4.8 or newer +* Clang 3.4.1 or newer + +#### Windows + +* Building Node: Visual Studio 2013 or Visual C++ Build Tools 2013 or newer +* Building native add-ons: Visual Studio 2013 or Visual C++ Build Tools 2013 + or newer + +## Building Node.js on supported platforms ### Unix / OS X Prerequisites: * `gcc` and `g++` 4.8 or newer, or -* `clang` and `clang++` 3.4 or newer +* `clang` and `clang++` 3.4.1 or newer * Python 2.6 or 2.7 * GNU Make 3.81 or newer On OS X, you will also need: * [Xcode](https://developer.apple.com/xcode/download/) - * You also need to install the `Command Line Tools` via Xcode. You can find + - You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Downloads` - * This step will install `gcc` and the related toolchain containing `make` + - This step will install `gcc` and the related toolchain containing `make` * After building, you may want to setup [firewall rules](tools/macosx-firewall.sh) to avoid popups asking to accept incoming network connections when running tests: @@ -53,6 +108,9 @@ $ make $ [sudo] make install ``` +Note that the above requires that `python` resolve to Python 2.6 or 2.7 +and not a newer version. + To run the tests: ```text @@ -263,9 +321,11 @@ It is possible to build Node.js with **Note**: building in this way does **not** allow you to claim that the runtime is FIPS 140-2 validated. Instead you can indicate that the runtime -uses a validated module. See the [security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf) +uses a validated module. See the +[security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf) page 60 for more details. In addition, the validation for the underlying module -is only valid if it is deployed in accordance with its [security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf). +is only valid if it is deployed in accordance with its +[security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf). If you need FIPS validated cryptography it is recommended that you read both the [security policy](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf) and [user guide](https://openssl.org/docs/fips/UserGuide-2.0.pdf). diff --git a/README.md b/README.md index 43f19ade786830..50974cb29c7671 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ the binary verification command above. ## Building Node.js See [BUILDING.md](BUILDING.md) for instructions on how to build -Node.js from source. +Node.js from source along with a list of officially supported platforms. ## Security From 1dc6b38dcfe539031957e352569f4d0c1206fe28 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Thu, 20 Oct 2016 15:38:54 -0400 Subject: [PATCH 03/15] test: add test for loading from global folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test executes with a copy of the node executable since $PREFIX/lib/node is relative to the executable location. PR-URL: https://github.com/nodejs/node/pull/9283 Reviewed-By: Sam Roberts Reviewed-By: Gibson Fahnestock Reviewed-By: João Reis Reviewed-By: Ben Noordhuis --- .../home-pkg-in-both/.node_libraries/foo.js | 1 + .../home-pkg-in-both/.node_modules/foo.js | 1 + .../.node_libraries/foo.js | 1 + .../.node_modules/foo.js | 1 + .../local-pkg/node_modules/foo.js | 1 + .../local-pkg/test.js | 2 + .../node_path/foo.js | 1 + .../test-module-loading-globalpaths.js | 101 ++++++++++++++++++ 8 files changed, 109 insertions(+) create mode 100644 test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_libraries/foo.js create mode 100644 test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_modules/foo.js create mode 100644 test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_libraries/.node_libraries/foo.js create mode 100644 test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_modules/.node_modules/foo.js create mode 100644 test/fixtures/test-module-loading-globalpaths/local-pkg/node_modules/foo.js create mode 100644 test/fixtures/test-module-loading-globalpaths/local-pkg/test.js create mode 100644 test/fixtures/test-module-loading-globalpaths/node_path/foo.js create mode 100644 test/parallel/test-module-loading-globalpaths.js diff --git a/test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_libraries/foo.js b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_libraries/foo.js new file mode 100644 index 00000000000000..eb278f95762215 --- /dev/null +++ b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_libraries/foo.js @@ -0,0 +1 @@ +exports.string = '$HOME/.node_libraries'; diff --git a/test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_modules/foo.js b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_modules/foo.js new file mode 100644 index 00000000000000..8a665b3e98cfe2 --- /dev/null +++ b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-both/.node_modules/foo.js @@ -0,0 +1 @@ +exports.string = '$HOME/.node_modules'; diff --git a/test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_libraries/.node_libraries/foo.js b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_libraries/.node_libraries/foo.js new file mode 100644 index 00000000000000..eb278f95762215 --- /dev/null +++ b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_libraries/.node_libraries/foo.js @@ -0,0 +1 @@ +exports.string = '$HOME/.node_libraries'; diff --git a/test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_modules/.node_modules/foo.js b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_modules/.node_modules/foo.js new file mode 100644 index 00000000000000..8a665b3e98cfe2 --- /dev/null +++ b/test/fixtures/test-module-loading-globalpaths/home-pkg-in-node_modules/.node_modules/foo.js @@ -0,0 +1 @@ +exports.string = '$HOME/.node_modules'; diff --git a/test/fixtures/test-module-loading-globalpaths/local-pkg/node_modules/foo.js b/test/fixtures/test-module-loading-globalpaths/local-pkg/node_modules/foo.js new file mode 100644 index 00000000000000..63e844e4d4060b --- /dev/null +++ b/test/fixtures/test-module-loading-globalpaths/local-pkg/node_modules/foo.js @@ -0,0 +1 @@ +exports.string = 'local'; diff --git a/test/fixtures/test-module-loading-globalpaths/local-pkg/test.js b/test/fixtures/test-module-loading-globalpaths/local-pkg/test.js new file mode 100644 index 00000000000000..8054983e992ce8 --- /dev/null +++ b/test/fixtures/test-module-loading-globalpaths/local-pkg/test.js @@ -0,0 +1,2 @@ +'use strict'; +console.log(require('foo').string); diff --git a/test/fixtures/test-module-loading-globalpaths/node_path/foo.js b/test/fixtures/test-module-loading-globalpaths/node_path/foo.js new file mode 100644 index 00000000000000..3ce43c49206f73 --- /dev/null +++ b/test/fixtures/test-module-loading-globalpaths/node_path/foo.js @@ -0,0 +1 @@ +exports.string = '$NODE_PATH'; diff --git a/test/parallel/test-module-loading-globalpaths.js b/test/parallel/test-module-loading-globalpaths.js new file mode 100644 index 00000000000000..d789f5409901ba --- /dev/null +++ b/test/parallel/test-module-loading-globalpaths.js @@ -0,0 +1,101 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const child_process = require('child_process'); +const pkgName = 'foo'; + +if (process.argv[2] === 'child') { + console.log(require(pkgName).string); +} else { + common.refreshTmpDir(); + + // Copy node binary into a test $PREFIX directory. + const prefixPath = path.join(common.tmpDir, 'install'); + fs.mkdirSync(prefixPath); + let testExecPath; + if (common.isWindows) { + testExecPath = path.join(prefixPath, path.basename(process.execPath)); + } else { + const prefixBinPath = path.join(prefixPath, 'bin'); + fs.mkdirSync(prefixBinPath); + testExecPath = path.join(prefixBinPath, path.basename(process.execPath)); + } + const mode = fs.statSync(process.execPath).mode; + fs.writeFileSync(testExecPath, fs.readFileSync(process.execPath)); + fs.chmodSync(testExecPath, mode); + + const runTest = (expectedString, env) => { + const child = child_process.execFileSync(testExecPath, + [ __filename, 'child' ], + { encoding: 'utf8', env: env }); + assert.strictEqual(child.trim(), expectedString); + }; + + const testFixturesDir = path.join(common.fixturesDir, + path.basename(__filename, '.js')); + + const env = Object.assign({}, process.env); + // Turn on module debug to aid diagnosing failures. + env['NODE_DEBUG'] = 'module'; + // Unset NODE_PATH. + delete env['NODE_PATH']; + + // Test empty global path. + const noPkgHomeDir = path.join(common.tmpDir, 'home-no-pkg'); + fs.mkdirSync(noPkgHomeDir); + env['HOME'] = env['USERPROFILE'] = noPkgHomeDir; + assert.throws( + () => { + child_process.execFileSync(testExecPath, [ __filename, 'child' ], + { encoding: 'utf8', env: env }); + }, + new RegExp('Cannot find module \'' + pkgName + '\'')); + + // Test module in $HOME/.node_modules. + const modHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_modules'); + env['HOME'] = env['USERPROFILE'] = modHomeDir; + runTest('$HOME/.node_modules', env); + + // Test module in $HOME/.node_libraries. + const libHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_libraries'); + env['HOME'] = env['USERPROFILE'] = libHomeDir; + runTest('$HOME/.node_libraries', env); + + // Test module both $HOME/.node_modules and $HOME/.node_libraries. + const bothHomeDir = path.join(testFixturesDir, 'home-pkg-in-both'); + env['HOME'] = env['USERPROFILE'] = bothHomeDir; + runTest('$HOME/.node_modules', env); + + // Test module in $PREFIX/lib/node. + // Write module into $PREFIX/lib/node. + const expectedString = '$PREFIX/lib/node'; + const prefixLibPath = path.join(prefixPath, 'lib'); + fs.mkdirSync(prefixLibPath); + const prefixLibNodePath = path.join(prefixLibPath, 'node'); + fs.mkdirSync(prefixLibNodePath); + const pkgPath = path.join(prefixLibNodePath, pkgName + '.js'); + fs.writeFileSync(pkgPath, 'exports.string = \'' + expectedString + '\';'); + + env['HOME'] = env['USERPROFILE'] = noPkgHomeDir; + runTest(expectedString, env); + + // Test module in all global folders. + env['HOME'] = env['USERPROFILE'] = bothHomeDir; + runTest('$HOME/.node_modules', env); + + // Test module in NODE_PATH is loaded ahead of global folders. + env['HOME'] = env['USERPROFILE'] = bothHomeDir; + env['NODE_PATH'] = path.join(testFixturesDir, 'node_path'); + runTest('$NODE_PATH', env); + + // Test module in local folder is loaded ahead of global folders. + const localDir = path.join(testFixturesDir, 'local-pkg'); + env['HOME'] = env['USERPROFILE'] = bothHomeDir; + env['NODE_PATH'] = path.join(testFixturesDir, 'node_path'); + const child = child_process.execFileSync(testExecPath, + [ path.join(localDir, 'test.js') ], + { encoding: 'utf8', env: env }); + assert.strictEqual(child.trim(), 'local'); +} From ba91c41478bfe3f3c07b56b8534a6c676ef6ae3d Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Tue, 25 Oct 2016 23:58:06 +0100 Subject: [PATCH 04/15] module: fix loading from global folders on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code was calculating $PREFIX/lib/node relative to process.execPath, but on Windows process.execPath is $PREFIX\node.exe whereas everywhere else process.execPath is $PREFIX/bin/node (where $PREFIX is the root of the installed Node.js). PR-URL: https://github.com/nodejs/node/pull/9283 Reviewed-By: Sam Roberts Reviewed-By: Gibson Fahnestock Reviewed-By: João Reis Reviewed-By: Ben Noordhuis --- lib/module.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/module.js b/lib/module.js index 36e0b160c99038..1a8dcfc4ad04a1 100644 --- a/lib/module.js +++ b/lib/module.js @@ -453,7 +453,16 @@ Module._initPaths = function() { homeDir = process.env.HOME; } - var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node')]; + // $PREFIX/lib/node, where $PREFIX is the root of the Node.js installation. + var prefixDir; + // process.execPath is $PREFIX/bin/node except on Windows where it is + // $PREFIX\node.exe. + if (isWindows) { + prefixDir = path.resolve(process.execPath, '..'); + } else { + prefixDir = path.resolve(process.execPath, '..', '..'); + } + var paths = [path.resolve(prefixDir, 'lib', 'node')]; if (homeDir) { paths.unshift(path.resolve(homeDir, '.node_libraries')); From 99749dccfe10668818c5451f62cf27a8eb6dc527 Mon Sep 17 00:00:00 2001 From: jBarz Date: Thu, 9 Mar 2017 08:33:59 -0500 Subject: [PATCH 05/15] tls: keep track of stream that is closed TLSWrap object keeps a pointer reference to the underlying TCPWrap object. This TCPWrap object could be closed and deleted by the event-loop which leaves us with a dangling pointer. So the TLSWrap object needs to track the "close" event on the TCPWrap object. PR-URL: https://github.com/nodejs/node/pull/11776 Reviewed-By: Fedor Indutny Reviewed-By: James M Snell Reviewed-By: Brian White --- lib/_tls_wrap.js | 6 ++++ src/tls_wrap.cc | 11 ++++++- src/tls_wrap.h | 1 + test/parallel/test-tls-socket-close.js | 43 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-tls-socket-close.js diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 31cbe3e65edfa9..bd153b43c0e33f 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -391,6 +391,12 @@ TLSSocket.prototype._wrapHandle = function(wrap) { res = null; }); + if (wrap) { + wrap.on('close', function() { + res.onStreamClose(); + }); + } + return res; }; diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index dd1b0e3b5f340f..7bc4f8d578a668 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -523,7 +523,7 @@ int TLSWrap::GetFD() { bool TLSWrap::IsAlive() { - return ssl_ != nullptr && stream_->IsAlive(); + return ssl_ != nullptr && stream_ != nullptr && stream_->IsAlive(); } @@ -783,6 +783,14 @@ void TLSWrap::EnableSessionCallbacks( } +void TLSWrap::OnStreamClose(const FunctionCallbackInfo& args) { + TLSWrap* wrap; + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + + wrap->stream_ = nullptr; +} + + void TLSWrap::DestroySSL(const FunctionCallbackInfo& args) { TLSWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); @@ -913,6 +921,7 @@ void TLSWrap::Initialize(Local target, env->SetProtoMethod(t, "enableSessionCallbacks", EnableSessionCallbacks); env->SetProtoMethod(t, "destroySSL", DestroySSL); env->SetProtoMethod(t, "enableCertCb", EnableCertCb); + env->SetProtoMethod(t, "onStreamClose", OnStreamClose); StreamBase::AddMethods(env, t, StreamBase::kFlagHasWritev); SSLWrap::AddMethods(env, t); diff --git a/src/tls_wrap.h b/src/tls_wrap.h index ba5eecbf0030e5..7f30ce99818841 100644 --- a/src/tls_wrap.h +++ b/src/tls_wrap.h @@ -135,6 +135,7 @@ class TLSWrap : public AsyncWrap, static void EnableCertCb( const v8::FunctionCallbackInfo& args); static void DestroySSL(const v8::FunctionCallbackInfo& args); + static void OnStreamClose(const v8::FunctionCallbackInfo& args); #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB static void GetServername(const v8::FunctionCallbackInfo& args); diff --git a/test/parallel/test-tls-socket-close.js b/test/parallel/test-tls-socket-close.js new file mode 100644 index 00000000000000..440c0c4ff7cde7 --- /dev/null +++ b/test/parallel/test-tls-socket-close.js @@ -0,0 +1,43 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const tls = require('tls'); +const fs = require('fs'); +const net = require('net'); + +const key = fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'); +const cert = fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'); + +const T = 100; + +// tls server +const tlsServer = tls.createServer({ cert, key }, (socket) => { + setTimeout(() => { + socket.on('error', (error) => { + assert.strictEqual(error.code, 'EINVAL'); + tlsServer.close(); + netServer.close(); + }); + socket.write('bar'); + }, T * 2); +}); + +// plain tcp server +const netServer = net.createServer((socket) => { + // if client wants to use tls + tlsServer.emit('connection', socket); + + socket.setTimeout(T, () => { + // this breaks if TLSSocket is already managing the socket: + socket.destroy(); + }); +}).listen(0, common.mustCall(function() { + + // connect client + tls.connect({ + host: 'localhost', + port: this.address().port, + rejectUnauthorized: false + }).write('foo'); +})); From ff1d61c11bb47287521091e8c3edff606ad5ead0 Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Mon, 31 Oct 2016 16:48:14 -0600 Subject: [PATCH 06/15] stream_base,tls_wrap: notify on destruct The TLSWrap constructor is passed a StreamBase* which it stores as TLSWrap::stream_, and is used to receive/send data along the pipeline (e.g. tls -> tcp). Problem is the lifetime of the instance that stream_ points to is independent of the lifetime of the TLSWrap instance. So it's possible for stream_ to be delete'd while the TLSWrap instance is still alive, allowing potential access to a then invalid pointer. Fix by having the StreamBase destructor null out TLSWrap::stream_; allowing all TLSWrap methods that rely on stream_ to do a check to see if it's available. While the test provided is fixed by this commit, it was also previously fixed by 478fabf. Regardless, leave the test in for better testing. PR-URL: https://github.com/nodejs/node/pull/11947 Reviewed-By: Franziska Hinkelmann Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- src/stream_base.h | 9 +++- src/tls_wrap.cc | 7 ++++ src/tls_wrap.h | 3 ++ .../test-tls-retain-handle-no-abort.js | 42 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-tls-retain-handle-no-abort.js diff --git a/src/stream_base.h b/src/stream_base.h index cdce46abc8dcd2..1ca21d96245471 100644 --- a/src/stream_base.h +++ b/src/stream_base.h @@ -135,10 +135,14 @@ class StreamResource { const uv_buf_t* buf, uv_handle_type pending, void* ctx); + typedef void (*DestructCb)(void* ctx); StreamResource() : bytes_read_(0) { } - virtual ~StreamResource() = default; + virtual ~StreamResource() { + if (!destruct_cb_.is_empty()) + destruct_cb_.fn(destruct_cb_.ctx); + } virtual int DoShutdown(ShutdownWrap* req_wrap) = 0; virtual int DoTryWrite(uv_buf_t** bufs, size_t* count); @@ -175,15 +179,18 @@ class StreamResource { inline void set_alloc_cb(Callback c) { alloc_cb_ = c; } inline void set_read_cb(Callback c) { read_cb_ = c; } + inline void set_destruct_cb(Callback c) { destruct_cb_ = c; } inline Callback after_write_cb() { return after_write_cb_; } inline Callback alloc_cb() { return alloc_cb_; } inline Callback read_cb() { return read_cb_; } + inline Callback destruct_cb() { return destruct_cb_; } private: Callback after_write_cb_; Callback alloc_cb_; Callback read_cb_; + Callback destruct_cb_; uint64_t bytes_read_; friend class StreamBase; diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 7bc4f8d578a668..5e004066a45c2e 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -66,6 +66,7 @@ TLSWrap::TLSWrap(Environment* env, stream_->set_after_write_cb({ OnAfterWriteImpl, this }); stream_->set_alloc_cb({ OnAllocImpl, this }); stream_->set_read_cb({ OnReadImpl, this }); + stream_->set_destruct_cb({ OnDestructImpl, this }); set_alloc_cb({ OnAllocSelf, this }); set_read_cb({ OnReadSelf, this }); @@ -661,6 +662,12 @@ void TLSWrap::OnReadImpl(ssize_t nread, } +void TLSWrap::OnDestructImpl(void* ctx) { + TLSWrap* wrap = static_cast(ctx); + wrap->clear_stream(); +} + + void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) { buf->base = static_cast(node::Malloc(suggested_size)); CHECK_NE(buf->base, nullptr); diff --git a/src/tls_wrap.h b/src/tls_wrap.h index 7f30ce99818841..d4c6636571eaba 100644 --- a/src/tls_wrap.h +++ b/src/tls_wrap.h @@ -52,6 +52,8 @@ class TLSWrap : public AsyncWrap, size_t self_size() const override { return sizeof(*this); } + void clear_stream() { stream_ = nullptr; } + protected: static const int kClearOutChunkSize = 16384; @@ -119,6 +121,7 @@ class TLSWrap : public AsyncWrap, const uv_buf_t* buf, uv_handle_type pending, void* ctx); + static void OnDestructImpl(void* ctx); void DoRead(ssize_t nread, const uv_buf_t* buf, uv_handle_type pending); diff --git a/test/parallel/test-tls-retain-handle-no-abort.js b/test/parallel/test-tls-retain-handle-no-abort.js new file mode 100644 index 00000000000000..43b3709fd5f85b --- /dev/null +++ b/test/parallel/test-tls-retain-handle-no-abort.js @@ -0,0 +1,42 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} +const tls = require('tls'); +const fs = require('fs'); +const util = require('util'); + +const sent = 'hello world'; +const serverOptions = { + isServer: true, + key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), + cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') +}; + +let ssl = null; + +process.on('exit', function() { + assert.ok(ssl !== null); + // If the internal pointer to stream_ isn't cleared properly then this + // will abort. + util.inspect(ssl); +}); + +const server = tls.createServer(serverOptions, function(s) { + s.on('data', function() { }); + s.on('end', function() { + server.close(); + s.destroy(); + }); +}).listen(0, function() { + const c = new tls.TLSSocket(); + ssl = c.ssl; + c.connect(this.address().port, function() { + c.end(sent); + }); +}); From 44260806a6fcbf554a9d60f5fd8acaeba071e26f Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Mon, 20 Mar 2017 16:26:10 -0600 Subject: [PATCH 07/15] Partial revert "tls: keep track of stream that is closed" This partually reverts commit 4cdb0e89d8daf7e1371c3b8d3f057940aa327d4a. A nullptr check in TSLWrap::IsAlive() and the added test were left. PR-URL: https://github.com/nodejs/node/pull/11947 Reviewed-By: Franziska Hinkelmann Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- lib/_tls_wrap.js | 6 ------ src/tls_wrap.cc | 9 --------- src/tls_wrap.h | 1 - 3 files changed, 16 deletions(-) diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index bd153b43c0e33f..31cbe3e65edfa9 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -391,12 +391,6 @@ TLSSocket.prototype._wrapHandle = function(wrap) { res = null; }); - if (wrap) { - wrap.on('close', function() { - res.onStreamClose(); - }); - } - return res; }; diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 5e004066a45c2e..056588e4957620 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -790,14 +790,6 @@ void TLSWrap::EnableSessionCallbacks( } -void TLSWrap::OnStreamClose(const FunctionCallbackInfo& args) { - TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); - - wrap->stream_ = nullptr; -} - - void TLSWrap::DestroySSL(const FunctionCallbackInfo& args) { TLSWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); @@ -928,7 +920,6 @@ void TLSWrap::Initialize(Local target, env->SetProtoMethod(t, "enableSessionCallbacks", EnableSessionCallbacks); env->SetProtoMethod(t, "destroySSL", DestroySSL); env->SetProtoMethod(t, "enableCertCb", EnableCertCb); - env->SetProtoMethod(t, "onStreamClose", OnStreamClose); StreamBase::AddMethods(env, t, StreamBase::kFlagHasWritev); SSLWrap::AddMethods(env, t); diff --git a/src/tls_wrap.h b/src/tls_wrap.h index d4c6636571eaba..7c70d364bdbd38 100644 --- a/src/tls_wrap.h +++ b/src/tls_wrap.h @@ -138,7 +138,6 @@ class TLSWrap : public AsyncWrap, static void EnableCertCb( const v8::FunctionCallbackInfo& args); static void DestroySSL(const v8::FunctionCallbackInfo& args); - static void OnStreamClose(const v8::FunctionCallbackInfo& args); #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB static void GetServername(const v8::FunctionCallbackInfo& args); From 54f5258582402644c35693d6fe2bd0a9933b0305 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 17 Mar 2017 15:31:14 +0100 Subject: [PATCH 08/15] tls: fix segfault on destroy after partial read OnRead() calls into JS land which can result in the SSL context object being destroyed on return. Check that `ssl_ != nullptr` afterwards. Fixes: https://github.com/nodejs/node/issues/11885 PR-URL: https://github.com/nodejs/node/pull/11898 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/tls_wrap.cc | 6 ++++ test/parallel/test-tls-socket-destroy.js | 36 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/parallel/test-tls-socket-destroy.js diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 056588e4957620..cab6a75c8c2a3e 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -427,6 +427,12 @@ void TLSWrap::ClearOut() { memcpy(buf.base, current, avail); OnRead(avail, &buf); + // Caveat emptor: OnRead() calls into JS land which can result in + // the SSL context object being destroyed. We have to carefully + // check that ssl_ != nullptr afterwards. + if (ssl_ == nullptr) + return; + read -= avail; current += avail; } diff --git a/test/parallel/test-tls-socket-destroy.js b/test/parallel/test-tls-socket-destroy.js new file mode 100644 index 00000000000000..27651f8ec7206a --- /dev/null +++ b/test/parallel/test-tls-socket-destroy.js @@ -0,0 +1,36 @@ +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} + +const fs = require('fs'); +const net = require('net'); +const tls = require('tls'); + +const key = fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'); +const cert = fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'); +const secureContext = tls.createSecureContext({ key, cert }); + +const server = net.createServer(common.mustCall((conn) => { + const options = { isServer: true, secureContext, server }; + const socket = new tls.TLSSocket(conn, options); + socket.once('data', common.mustCall(() => { + socket._destroySSL(); // Should not crash. + server.close(); + })); +})); + +server.listen(0, function() { + const options = { + port: this.address().port, + rejectUnauthorized: false, + }; + tls.connect(options, function() { + this.write('*'.repeat(1 << 20)); // Write more data than fits in a frame. + this.on('error', this.destroy); // Server closes connection on us. + }); +}); From ab3fdf531fe0536ae6b3a657d7fb73adc0881a99 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Mon, 20 Mar 2017 10:04:48 -0700 Subject: [PATCH 09/15] deps: cherry-pick ca0f9573 from V8 upstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message: Trigger OOM crash if no memory returned in v8::ArrayBuffer::New and v… …8::SharedArrayBuffer::New. This API does not allow reporting failure, but we should crash rather than have the caller get an ArrayBuffer that isn't properly set up. BUG=chromium:681843 Review-Url: https://codereview.chromium.org/2641953002 Cr-Commit-Position: refs/heads/master@{#42511} PR-URL: https://github.com/nodejs/node/pull/11940 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Ben Noordhuis --- deps/v8/include/v8-version.h | 2 +- deps/v8/src/api.cc | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index fc3292b05ff939..2101944d14770b 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 4 #define V8_MINOR_VERSION 5 #define V8_BUILD_NUMBER 103 -#define V8_PATCH_LEVEL 46 +#define V8_PATCH_LEVEL 47 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index ec0f805876fd9c..594d2ebcf20baa 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -6580,7 +6580,11 @@ Local v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) { ENTER_V8(i_isolate); i::Handle obj = i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); - i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length); + // TODO(jbroman): It may be useful in the future to provide a MaybeLocal + // version that throws an exception or otherwise does not crash. + if (!i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length)) { + i::FatalProcessOutOfMemory("v8::ArrayBuffer::New"); + } return Utils::ToLocal(obj); } @@ -6775,8 +6779,12 @@ Local v8::SharedArrayBuffer::New(Isolate* isolate, ENTER_V8(i_isolate); i::Handle obj = i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared); - i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length, true, - i::SharedFlag::kShared); + // TODO(jborman): It may be useful in the future to provide a MaybeLocal + // version that throws an exception or otherwise does not crash. + if (!i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length, true, + i::SharedFlag::kShared)) { + i::FatalProcessOutOfMemory("v8::SharedArrayBuffer::New"); + } return Utils::ToLocalShared(obj); } From 8ed18a1429e62d19bffc04b696a517e18c7475b2 Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Tue, 14 Mar 2017 18:22:53 +0100 Subject: [PATCH 10/15] src: ensure that fd 0-2 are valid on windows Check that stdin, stdout and stderr are valid file descriptors on Windows. If not, reopen them with 'nul' file. Refs: https://github.com/nodejs/node/pull/875 Fixes: https://github.com/nodejs/node/issues/11656 PR-URL: https://github.com/nodejs/node/pull/11863 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel Reviewed-By: Anna Henningsen --- src/node.cc | 13 +++++++++++++ test/fixtures/spawn_closed_stdio.py | 8 ++++++++ test/parallel/test-stdio-closed.js | 14 +++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/spawn_closed_stdio.py diff --git a/src/node.cc b/src/node.cc index 63c49c49b09a5c..b48c4b06a15b6c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3995,6 +3995,19 @@ inline void PlatformInit() { } while (min + 1 < max); } #endif // __POSIX__ +#ifdef _WIN32 + for (int fd = 0; fd <= 2; ++fd) { + auto handle = reinterpret_cast(_get_osfhandle(fd)); + if (handle == INVALID_HANDLE_VALUE || + GetFileType(handle) == FILE_TYPE_UNKNOWN) { + // Ignore _close result. If it fails or not depends on used Windows + // version. We will just check _open result. + _close(fd); + if (fd != _open("nul", _O_RDWR)) + ABORT(); + } + } +#endif // _WIN32 } diff --git a/test/fixtures/spawn_closed_stdio.py b/test/fixtures/spawn_closed_stdio.py new file mode 100644 index 00000000000000..b5de2552c2b13e --- /dev/null +++ b/test/fixtures/spawn_closed_stdio.py @@ -0,0 +1,8 @@ +import os +import sys +import subprocess +os.close(0) +os.close(1) +os.close(2) +exit_code = subprocess.call(sys.argv[1:], shell=False) +sys.exit(exit_code) diff --git a/test/parallel/test-stdio-closed.js b/test/parallel/test-stdio-closed.js index 98e4f980d50dd6..2313140a26aea7 100644 --- a/test/parallel/test-stdio-closed.js +++ b/test/parallel/test-stdio-closed.js @@ -3,9 +3,21 @@ const common = require('../common'); const assert = require('assert'); const spawn = require('child_process').spawn; const fs = require('fs'); +const path = require('path'); if (common.isWindows) { - common.skip('platform not supported.'); + if (process.argv[2] === 'child') { + process.stdin; + process.stdout; + process.stderr; + return; + } + const python = process.env.PYTHON || 'python'; + const script = path.join(common.fixturesDir, 'spawn_closed_stdio.py'); + const proc = spawn(python, [script, process.execPath, __filename, 'child']); + proc.on('exit', common.mustCall(function(exitCode) { + assert.strictEqual(exitCode, 0); + })); return; } From 7a1920dc84bd68320dd2a19e071fff3a8eac4ea2 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Wed, 8 Mar 2017 13:39:57 +0100 Subject: [PATCH 11/15] test: add hasCrypto check to tls-socket-close Currently test-tls-socket-close will fail if node was built using --without-ssl. This commit adds a check to verify is crypto support exists and if not skip this test. PR-URL: https://github.com/nodejs/node/pull/11911 Reviewed-By: Ben Noordhuis Reviewed-By: Luigi Pinca Reviewed-By: Yuta Hiroto Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- test/parallel/test-tls-socket-close.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/parallel/test-tls-socket-close.js b/test/parallel/test-tls-socket-close.js index 440c0c4ff7cde7..4e7382f3407a8a 100644 --- a/test/parallel/test-tls-socket-close.js +++ b/test/parallel/test-tls-socket-close.js @@ -1,5 +1,9 @@ 'use strict'; const common = require('../common'); +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} const assert = require('assert'); const tls = require('tls'); From eb393f9ae1bf551c480777715923231485bd7d21 Mon Sep 17 00:00:00 2001 From: Nikolai Vavilov Date: Wed, 22 Mar 2017 23:31:12 +0200 Subject: [PATCH 12/15] src: fix base64 decoding Make sure trailing garbage is not treated as a valid base64 character. Fixes: https://github.com/nodejs/node/issues/11987 PR-URL: https://github.com/nodejs/node/pull/11995 Reviewed-By: Anna Henningsen --- src/string_bytes.cc | 4 ++-- test/parallel/test-buffer-alloc.js | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/string_bytes.cc b/src/string_bytes.cc index a650ac0b00452e..8cb669e223eeba 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -174,13 +174,13 @@ size_t base64_decode_slow(char* dst, size_t dstlen, size_t k = 0; for (;;) { #define V(expr) \ - while (i < srclen) { \ + for (;;) { \ const uint8_t c = src[i]; \ lo = unbase64(c); \ i += 1; \ if (lo < 64) \ break; /* Legal character. */ \ - if (c == '=') \ + if (c == '=' || i >= srclen) \ return k; \ } \ expr; \ diff --git a/test/parallel/test-buffer-alloc.js b/test/parallel/test-buffer-alloc.js index d3564ab81b8d92..49d628bfec58b0 100644 --- a/test/parallel/test-buffer-alloc.js +++ b/test/parallel/test-buffer-alloc.js @@ -696,6 +696,10 @@ assert.equal(dot.toString('base64'), '//4uAA=='); // Regression test for https://github.com/nodejs/node/issues/3496. assert.equal(Buffer.from('=bad'.repeat(1e4), 'base64').length, 0); +// Regression test for https://github.com/nodejs/node/issues/11987. +assert.deepStrictEqual(Buffer.from('w0 ', 'base64'), + Buffer.from('w0', 'base64')); + { // Creating buffers larger than pool size. const l = Buffer.poolSize + 5; From b5b78b12b86658f4bc8dc646c17f04c05dc50c6d Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Thu, 20 Apr 2017 15:41:25 +0200 Subject: [PATCH 13/15] src: add fcntl.h include to node.cc https://github.com/nodejs/node/pull/11863 adds _O_RDWR to node.cc which is defined in fcntl.h. This adds this include directly to node.cc. PR-URL: https://github.com/nodejs/node/pull/12540 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Gibson Fahnestock Reviewed-By: Anna Henningsen Reviewed-By: Myles Borins --- src/node.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/node.cc b/src/node.cc index b48c4b06a15b6c..a5390e12f3e2d2 100644 --- a/src/node.cc +++ b/src/node.cc @@ -51,6 +51,7 @@ #endif #include +#include // _O_RDWR #include // PATH_MAX #include #include From 6040efd7dcf6e7edce9471799a81b23622d6926f Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sat, 23 Jul 2016 14:11:50 -0700 Subject: [PATCH 14/15] test: fix flaky test-tls-wrap-timeout Competing timers were causing a race condition and thus the test was flaky. Instead, we check an object property on process exit. Fixes: https://github.com/nodejs/node/issues/7650 Backport-PR-URL: https://github.com/nodejs/node/pull/12567 PR-URL: https://github.com/nodejs/node/pull/7857 Reviewed-By: Santiago Gimeno Reviewed-By: Fedor Indutny Reviewed-By: jasnell - James M Snell --- test/parallel/test-tls-wrap-timeout.js | 50 ++++++++++++++++---------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/test/parallel/test-tls-wrap-timeout.js b/test/parallel/test-tls-wrap-timeout.js index ab0f307a970bb3..0454242d92ecb6 100644 --- a/test/parallel/test-tls-wrap-timeout.js +++ b/test/parallel/test-tls-wrap-timeout.js @@ -1,42 +1,54 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); if (!common.hasCrypto) { common.skip('missing crypto'); return; } -var tls = require('tls'); +const assert = require('assert'); +const tls = require('tls'); -var net = require('net'); -var fs = require('fs'); +const net = require('net'); +const fs = require('fs'); -var options = { +const options = { key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') }; -var server = tls.createServer(options, function(c) { - setTimeout(function() { - c.write('hello'); - setTimeout(function() { - c.destroy(); - server.close(); - }, 150); - }, 150); -}); +const server = tls.createServer(options, common.mustCall((c) => { + setImmediate(() => { + c.write('hello', () => { + setImmediate(() => { + c.destroy(); + server.close(); + }); + }); + }); +})); + +var socket; +var lastIdleStart; -server.listen(0, function() { - var socket = net.connect(this.address().port, function() { - var s = socket.setTimeout(common.platformTimeout(240), function() { +server.listen(0, () => { + socket = net.connect(server.address().port, function() { + const s = socket.setTimeout(Number.MAX_VALUE, function() { throw new Error('timeout'); }); assert.ok(s instanceof net.Socket); - var tsocket = tls.connect({ + assert.notStrictEqual(socket._idleTimeout, -1); + lastIdleStart = socket._idleStart; + + const tsocket = tls.connect({ socket: socket, rejectUnauthorized: false }); tsocket.resume(); }); }); + +process.on('exit', () => { + assert.strictEqual(socket._idleTimeout, -1); + assert(lastIdleStart < socket._idleStart); +}); From 788f2803e61d19600044a757806372ae42a8c4d3 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Tue, 18 Apr 2017 20:12:12 -0400 Subject: [PATCH 15/15] 2017-05-02, Version 4.8.3 'Argon' (Maintenance) Notable Changes: * module: - The module loading global fallback to the Node executable's directory now works correctly on Windows. (Richard Lau) https://github.com/nodejs/node/pull/9283 * src: - fix base64 decoding in rare edgecase (Nikolai Vavilov) https://github.com/nodejs/node/pull/11995 * tls: - fix rare segmentation faults when using TLS * (Trevor Norris) https://github.com/nodejs/node/pull/11947 * (Ben Noordhuis) https://github.com/nodejs/node/pull/11898 * (jBarz) https://github.com/nodejs/node/pull/11776 PR-URL: https://github.com/nodejs/node/pull/12499 --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ src/node_version.h | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5544099f78f6e5..c54b2eee2b1605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Node.js ChangeLog +## 2017-05-02, Version 4.8.3 'Argon' (Maintenance), @MylesBorins + +### Notable Changes + +* **module**: + - The [module loading global fallback](https://nodejs.org/dist/latest-v4.x/docs/api/modules.html#modules_loading_from_the_global_folders) to the Node executable's directory now works correctly on Windows. (Richard Lau) [#9283](https://github.com/nodejs/node/pull/9283) +* **src**: + - fix base64 decoding in rare edgecase (Nikolai Vavilov) [#11995](https://github.com/nodejs/node/pull/11995) +* **tls**: + - fix rare segmentation faults when using TLS + * (Trevor Norris) [#11947](https://github.com/nodejs/node/pull/11947) + * (Ben Noordhuis) [#11898](https://github.com/nodejs/node/pull/11898) + * (jBarz) [#11776](https://github.com/nodejs/node/pull/11776) + +### Commits + +* [[`44260806a6`](https://github.com/nodejs/node/commit/44260806a6)] - Partial revert "tls: keep track of stream that is closed" (Trevor Norris) [#11947](https://github.com/nodejs/node/pull/11947) +* [[`ab3fdf531f`](https://github.com/nodejs/node/commit/ab3fdf531f)] - **deps**: cherry-pick ca0f9573 from V8 upstream (Ali Ijaz Sheikh) [#11940](https://github.com/nodejs/node/pull/11940) +* [[`07b92a3c0b`](https://github.com/nodejs/node/commit/07b92a3c0b)] - **doc**: add supported platforms list for v4.x (Michael Dawson) [#12091](https://github.com/nodejs/node/pull/12091) +* [[`ba91c41478`](https://github.com/nodejs/node/commit/ba91c41478)] - **module**: fix loading from global folders on Windows (Richard Lau) [#9283](https://github.com/nodejs/node/pull/9283) +* [[`b5b78b12b8`](https://github.com/nodejs/node/commit/b5b78b12b8)] - **src**: add fcntl.h include to node.cc (Bartosz Sosnowski) [#12540](https://github.com/nodejs/node/pull/12540) +* [[`eb393f9ae1`](https://github.com/nodejs/node/commit/eb393f9ae1)] - **src**: fix base64 decoding (Nikolai Vavilov) [#11995](https://github.com/nodejs/node/pull/11995) +* [[`8ed18a1429`](https://github.com/nodejs/node/commit/8ed18a1429)] - **src**: ensure that fd 0-2 are valid on windows (Bartosz Sosnowski) [#11863](https://github.com/nodejs/node/pull/11863) +* [[`ff1d61c11b`](https://github.com/nodejs/node/commit/ff1d61c11b)] - **stream_base,tls_wrap**: notify on destruct (Trevor Norris) [#11947](https://github.com/nodejs/node/pull/11947) +* [[`6040efd7dc`](https://github.com/nodejs/node/commit/6040efd7dc)] - **test**: fix flaky test-tls-wrap-timeout (Rich Trott) [#7857](https://github.com/nodejs/node/pull/7857) +* [[`7a1920dc84`](https://github.com/nodejs/node/commit/7a1920dc84)] - **test**: add hasCrypto check to tls-socket-close (Daniel Bevenius) [#11911](https://github.com/nodejs/node/pull/11911) +* [[`1dc6b38dcf`](https://github.com/nodejs/node/commit/1dc6b38dcf)] - **test**: add test for loading from global folders (Richard Lau) [#9283](https://github.com/nodejs/node/pull/9283) +* [[`54f5258582`](https://github.com/nodejs/node/commit/54f5258582)] - **tls**: fix segfault on destroy after partial read (Ben Noordhuis) [#11898](https://github.com/nodejs/node/pull/11898) +* [[`99749dccfe`](https://github.com/nodejs/node/commit/99749dccfe)] - **tls**: keep track of stream that is closed (jBarz) [#11776](https://github.com/nodejs/node/pull/11776) +* [[`6d3aaa72a8`](https://github.com/nodejs/node/commit/6d3aaa72a8)] - **tls**: TLSSocket emits 'error' on handshake failure (Mariusz 'koder' Chwalba) [#8805](https://github.com/nodejs/node/pull/8805) + ## 2017-04-04, Version 4.8.2 'Argon' (Maintenance), @MylesBorins This is a maintenance release to fix a memory leak that was introduced in 4.8.1. diff --git a/src/node_version.h b/src/node_version.h index 5b519561cc8b37..8bfd98c57ea273 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -8,7 +8,7 @@ #define NODE_VERSION_IS_LTS 1 #define NODE_VERSION_LTS_CODENAME "Argon" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)