forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-tls-destroy-ssl-with-pending-write.js
More file actions
56 lines (48 loc) · 1.77 KB
/
test-tls-destroy-ssl-with-pending-write.js
File metadata and controls
56 lines (48 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
'use strict';
// Regression test for TLSWrap use-after-free when destroySSL() is called
// while an underlying stream write is still in flight.
//
// EncOut() passes pointers into the enc_out_ BIO's internal buffer to the
// underlying stream via uv_write(). If the SSL context is freed before that
// write completes, libuv accesses freed memory (SIGSEGV).
//
// The GC weak callback path triggers the same Destroy() code when a
// TLSSocket with pending writes is collected without an explicit destroy().
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const fixtures = require('../common/fixtures');
const tls = require('node:tls');
const server = tls.createServer({
key: fixtures.readKey('agent1-key.pem'),
cert: fixtures.readKey('agent1-cert.pem'),
}, (socket) => {
// Do not read — TCP backpressure keeps client writes pending in the
// TLSWrap's underlying stream so write_size_ stays non-zero.
socket.pause();
});
server.listen(0, common.mustCall(() => {
const { port } = server.address();
let remaining = 10;
for (let i = 0; i < 10; i++) {
const socket = tls.connect(
{ port, host: '127.0.0.1', rejectUnauthorized: false },
common.mustCall(() => {
// Queue a write large enough to stay pending (server never reads).
socket.write(Buffer.alloc(1024 * 1024));
// Simulate the GC weak callback path: free the SSL context while
// the underlying stream write is still in flight.
if (socket._handle && socket._handle.destroySSL) {
socket._handle.destroySSL();
}
setTimeout(() => {
socket.destroy();
if (--remaining === 0) {
server.close();
}
}, 50);
}),
);
socket.on('error', () => {});
}
}));