From 68d76623549b40732f9bbdb2f625509c93e3457b Mon Sep 17 00:00:00 2001 From: Nitzan Uziely Date: Sat, 10 Apr 2021 02:07:56 +0300 Subject: [PATCH] tls: fix session and keylog add listener segfault Fix an issue where adding a session or keylog listener on a tlsSocket after it was destroyed caused a segfault. fixes: https://github.com/nodejs/node/issues/38133 fixes: https://github.com/nodejs/node/issues/38135 --- lib/_tls_wrap.js | 8 +++++-- test/parallel/test-tls-tlswrap-segfault-2.js | 24 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-tls-tlswrap-segfault-2.js diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 869bbda42f7898..9ecd92021de17f 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -689,7 +689,9 @@ TLSSocket.prototype._init = function(socket, wrap) { if (event !== 'keylog') return; - ssl.enableKeylogCallback(); + // Guard against enableKeylogCallback after destroy + if (!this._handle) return; + this._handle.enableKeylogCallback(); // Remove this listener since it's no longer needed. this.removeListener('newListener', keylogNewListener); @@ -733,7 +735,9 @@ TLSSocket.prototype._init = function(socket, wrap) { if (event !== 'session') return; - ssl.enableSessionCallbacks(); + // Guard against enableSessionCallbacks after destroy + if (!this._handle) return; + this._handle.enableSessionCallbacks(); // Remove this listener since it's no longer needed. this.removeListener('newListener', newListener); diff --git a/test/parallel/test-tls-tlswrap-segfault-2.js b/test/parallel/test-tls-tlswrap-segfault-2.js new file mode 100644 index 00000000000000..f1d1ec330995e5 --- /dev/null +++ b/test/parallel/test-tls-tlswrap-segfault-2.js @@ -0,0 +1,24 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +// This test ensures that Node.js doesn't incur a segfault while +// adding session or keylog listeners. +// https://github.com/nodejs/node/issues/38133 +// https://github.com/nodejs/node/issues/38135 + +const tls = require('tls'); +const tlsSocketKeyLog = tls.connect('cause-error'); +tlsSocketKeyLog.on('error', () => { + setTimeout(() => { + tlsSocketKeyLog.on('keylog', () => { }); + }, 10); +}); + +const tlsSocketSession = tls.connect('cause-error-2'); +tlsSocketSession.on('error', (e) => { + setTimeout(() => { + tlsSocketSession.on('keylog', () => { }); + }, 10); +});