From f71be242cadcfda59dc9e1042e9a2fff3504450a Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Tue, 9 Feb 2016 16:00:24 -0500 Subject: [PATCH] tls: nullify `.ssl` on handle close This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: #5108 PR-URL: https://github.com/nodejs/node/pull/5168 Reviewed-By: Shigeki Ohtsu --- lib/_tls_wrap.js | 3 ++ test/parallel/test-tls-regr-gh-5108.js | 42 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 test/parallel/test-tls-regr-gh-5108.js diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index ca5933c8ab..2077bf0846 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -313,6 +313,9 @@ proxiedMethods.forEach(function(name) { }); tls_wrap.TLSWrap.prototype.close = function closeProxy(cb) { + if (this.owner) + this.owner.ssl = null; + if (this._parentWrap && this._parentWrap._handle === this._parent) { this._parentWrap.once('close', cb); return this._parentWrap.destroy(); diff --git a/test/parallel/test-tls-regr-gh-5108.js b/test/parallel/test-tls-regr-gh-5108.js new file mode 100644 index 0000000000..5efcb76eab --- /dev/null +++ b/test/parallel/test-tls-regr-gh-5108.js @@ -0,0 +1,42 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) { + console.log('1..0 # Skipped: missing crypto'); + return; +} + +const assert = require('assert'); +const tls = require('tls'); +const fs = require('fs'); + +const options = { + key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), + cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') +}; + + +const server = tls.createServer(options, function(s) { + s.end('hello'); +}).listen(common.PORT, function() { + const opts = { + port: common.PORT, + rejectUnauthorized: false + }; + const client = tls.connect(opts, function() { + putImmediate(client); + }); +}); + + +function putImmediate(client) { + setImmediate(function() { + if (client.ssl) { + const fd = client.ssl.fd; + assert(!!fd); + putImmediate(client); + } else { + server.close(); + } + }); +}