From 80f37a5708b08b020408002c8ea5624fa5680a7e 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 | 19 +++++++++++++++++++ 2 files changed, 25 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..dad7a548dca1c3 --- /dev/null +++ b/test/parallel/test-tls-tlswrap-segfault-2.js @@ -0,0 +1,19 @@ +// 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', (e) => { + setTimeout(()=> { + tlsSocketKeyLog.on('keylog',()=>{}); + }, 10); +}); + +const tlsSocketSession = tls.connect('cause-error-2'); +tlsSocketSession.on('error', (e) => { + setTimeout(()=> { + tlsSocketSession.on('keylog',()=>{}); + }, 10); +});