-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tls: nullify .ssl
on handle close
#5168
Conversation
@bnoordhuis @shigeki I think proper fix will be to avoid calling |
@indutny I will test this soon, sorry for the delay. |
@ChALkeR no problem at all. Thanks for looking! |
Gosh, forgot to commit test. Happens every other time! |
This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: nodejs#5108
The fix works for me in both the small and the original testcase, thanks! |
@indutny I still cannot figure out what causes this error. The test case seems to be equivalent to the followings and it also leads seg faults. const server = tls.createServer(opts, function(c) {
c.end();
}).listen(common.PORT, function() {
var client = tls.connect({
port: common.PORT,
rejectUnauthorized: false
}, function() {
client.removeAllListeners('close');
client.on('close', function() {
setImmediate(function() {
console.log(client.ssl);
});
});
server.close();
});
}); Does the bhttp module also remove or shift the built-in close listener? Otherwise does it have a something else other reason? |
/cc @joepie91 for |
I can't say that I fully understand the issue or how it is being resolved (as I'm not very familiar with Node core yet), but the I'm not touching |
I've got that 'use strict';
const common = require('../common');
if (!common.hasCrypto) {
console.log('1..0 # Skipped: missing crypto');
return;
}
const assert = require('assert');
const tls = require('tls');
const fs = require('fs');
const options = {
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
};
const server = tls.createServer(options, function(s) {
s.end('hello');
}).listen(common.PORT, function() {
const opts = {port: common.PORT,
rejectUnauthorized: false};
const client = tls.connect(opts, function() {
putImmediate(client);
});
});
function putImmediate(client) {
setImmediate(function() {
if (client.ssl) {
const fd = client.ssl.fd;
assert(!!fd);
putImmediate(client);
} else {
server.close();
}
});
} The fix in this PR can resolve the issue. LGTM for a intermediate fix. |
@shigeki do you mind if I will include your test? It seems to be much better than mine. |
@indutny No problem for using the test. I reconsider this fix in this PR and had a question. With this patch, |
client._events.close.unshift(common.mustCall(function() { | ||
setImmediate(function() { | ||
// Make it crash on unpatched node.js | ||
var fd = client.ssl && client.ssl.fd; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the intention is to fail the test here, why not assert
it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because assert below will fail, and it won't crash.
Landed in aa05269, thank you! |
This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: #5108 PR-URL: #5168 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
Thanks! |
This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: #5108 PR-URL: #5168 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: nodejs#5108 PR-URL: nodejs#5168 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: #5108 PR-URL: #5168 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: #5108 PR-URL: #5168 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
This is an intermediate fix for an issue of accessing `TLSWrap` fields after the parent handle was destroyed. While `close` listener cleans up this field automatically, it can be done even earlier at the `TLSWrap.close` call. Proper fix is going to be submitted and landed after this one. Fix: #5108 PR-URL: #5168 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
This is an intermediate fix for an issue of accessing
TLSWrap
fieldsafter the parent handle was destroyed. While
close
listener cleans upthis field automatically, it can be done even earlier at the
TLSWrap.close
call.Proper fix is going to be submitted and landed after this one.
Fix: #5108
R = @bnoordhuis or @shigeki
cc @nodejs/crypto