Skip to content

Commit c626734

Browse files
bnoordhuisitaloacasas
authored andcommitted
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: #11885 PR-URL: #11898 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 0c00b65 commit c626734

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/tls_wrap.cc

+6
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,12 @@ void TLSWrap::ClearOut() {
425425
memcpy(buf.base, current, avail);
426426
OnRead(avail, &buf);
427427

428+
// Caveat emptor: OnRead() calls into JS land which can result in
429+
// the SSL context object being destroyed. We have to carefully
430+
// check that ssl_ != nullptr afterwards.
431+
if (ssl_ == nullptr)
432+
return;
433+
428434
read -= avail;
429435
current += avail;
430436
}
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
if (!common.hasCrypto) {
6+
common.skip('missing crypto');
7+
return;
8+
}
9+
10+
const fs = require('fs');
11+
const net = require('net');
12+
const tls = require('tls');
13+
14+
const key = fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem');
15+
const cert = fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem');
16+
const secureContext = tls.createSecureContext({ key, cert });
17+
18+
const server = net.createServer(common.mustCall((conn) => {
19+
const options = { isServer: true, secureContext, server };
20+
const socket = new tls.TLSSocket(conn, options);
21+
socket.once('data', common.mustCall(() => {
22+
socket._destroySSL(); // Should not crash.
23+
server.close();
24+
}));
25+
}));
26+
27+
server.listen(0, function() {
28+
const options = {
29+
port: this.address().port,
30+
rejectUnauthorized: false,
31+
};
32+
tls.connect(options, function() {
33+
this.write('*'.repeat(1 << 20)); // Write more data than fits in a frame.
34+
this.on('error', this.destroy); // Server closes connection on us.
35+
});
36+
});

0 commit comments

Comments
 (0)