Skip to content

Commit e95cc8a

Browse files
committed
tls: unconsume stream on destroy
When the TLS stream is destroyed for whatever reason, we should unset all callbacks on the underlying transport stream. Fixes: nodejs#17475
1 parent 7a055f1 commit e95cc8a

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

src/tls_wrap.cc

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,15 @@ TLSWrap::~TLSWrap() {
101101
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
102102
sni_context_.Reset();
103103
#endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
104+
105+
if (stream_ == nullptr)
106+
return;
107+
stream_->set_destruct_cb({ nullptr, nullptr });
108+
stream_->set_after_write_cb({ nullptr, nullptr });
109+
stream_->set_alloc_cb({ nullptr, nullptr });
110+
stream_->set_read_cb({ nullptr, nullptr });
111+
stream_->set_destruct_cb({ nullptr, nullptr });
112+
stream_->Unconsume();
104113
}
105114

106115

@@ -564,12 +573,16 @@ uint32_t TLSWrap::UpdateWriteQueueSize(uint32_t write_queue_size) {
564573

565574

566575
int TLSWrap::ReadStart() {
567-
return stream_->ReadStart();
576+
if (stream_ != nullptr)
577+
return stream_->ReadStart();
578+
return 0;
568579
}
569580

570581

571582
int TLSWrap::ReadStop() {
572-
return stream_->ReadStop();
583+
if (stream_ != nullptr)
584+
return stream_->ReadStop();
585+
return 0;
573586
}
574587

575588

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Flags: --expose-gc
2+
'use strict';
3+
4+
// Regression test for https://github.com/nodejs/node/issues/17475
5+
// Unfortunately, this tests only "works" reliably when checked with valgrind or
6+
// a similar tool.
7+
8+
/* eslint-disable no-unused-vars */
9+
10+
const common = require('../common');
11+
if (!common.hasCrypto)
12+
common.skip('missing crypto');
13+
14+
const assert = require('assert');
15+
const { TLSSocket } = require('tls');
16+
const makeDuplexPair = require('../common/duplexpair');
17+
18+
let { clientSide } = makeDuplexPair();
19+
20+
let clientTLS = new TLSSocket(clientSide, { isServer: false });
21+
let clientTLSHandle = clientTLS._handle;
22+
23+
setImmediate(() => {
24+
clientTLS = null;
25+
global.gc();
26+
clientTLSHandle = null;
27+
global.gc();
28+
setImmediate(() => {
29+
clientSide = null;
30+
global.gc();
31+
});
32+
});

0 commit comments

Comments
 (0)