tls: prevent use-after-free
* Destroy `SSL*` and friends on a next tick to make sure that we are not doing it in one of the OpenSSL callbacks * Add more checks to the C++ methods that might be invoked during destructor's pending queue cleanup Fix: https://github.com/joyent/node/issues/8780 Fix: https://github.com/iojs/io.js/issues/1696 PR-URL: https://github.com/nodejs/io.js/pull/1702 Reviewed-By: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
5795e835a1
commit
75930bb38c
@ -305,13 +305,18 @@ TLSSocket.prototype._wrapHandle = function(handle) {
|
||||
});
|
||||
|
||||
this.on('close', function() {
|
||||
this._destroySSL();
|
||||
// Make sure we are not doing it on OpenSSL's stack
|
||||
setImmediate(destroySSL, this);
|
||||
res = null;
|
||||
});
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
function destroySSL(self) {
|
||||
self._destroySSL();
|
||||
}
|
||||
|
||||
TLSSocket.prototype._destroySSL = function _destroySSL() {
|
||||
if (!this.ssl) return;
|
||||
this.ssl.destroySSL();
|
||||
|
@ -337,6 +337,9 @@ void TLSWrap::EncOutCb(WriteWrap* req_wrap, int status) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wrap->ssl_ == nullptr)
|
||||
return;
|
||||
|
||||
// Commit
|
||||
NodeBIO::FromBIO(wrap->enc_out_)->Read(nullptr, wrap->write_size_);
|
||||
|
||||
@ -554,6 +557,7 @@ int TLSWrap::DoWrite(WriteWrap* w,
|
||||
size_t count,
|
||||
uv_stream_t* send_handle) {
|
||||
CHECK_EQ(send_handle, nullptr);
|
||||
CHECK_NE(ssl_, nullptr);
|
||||
|
||||
bool empty = true;
|
||||
|
||||
@ -627,6 +631,11 @@ void TLSWrap::OnAfterWriteImpl(WriteWrap* w, void* ctx) {
|
||||
void TLSWrap::OnAllocImpl(size_t suggested_size, uv_buf_t* buf, void* ctx) {
|
||||
TLSWrap* wrap = static_cast<TLSWrap*>(ctx);
|
||||
|
||||
if (wrap->ssl_ == nullptr) {
|
||||
*buf = uv_buf_init(nullptr, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = 0;
|
||||
buf->base = NodeBIO::FromBIO(wrap->enc_in_)->PeekWritable(&size);
|
||||
buf->len = size;
|
||||
@ -747,6 +756,10 @@ void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
|
||||
void TLSWrap::EnableSessionCallbacks(
|
||||
const FunctionCallbackInfo<Value>& args) {
|
||||
TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
|
||||
if (wrap->ssl_ == nullptr) {
|
||||
return wrap->env()->ThrowTypeError(
|
||||
"EnableSessionCallbacks after destroySSL");
|
||||
}
|
||||
wrap->enable_session_callbacks();
|
||||
NodeBIO::FromBIO(wrap->enc_in_)->set_initial(kMaxHelloLength);
|
||||
wrap->hello_parser_.Start(SSLWrap<TLSWrap>::OnClientHello,
|
||||
|
@ -61,6 +61,7 @@ var server = tls.createServer({
|
||||
|
||||
socket.end('hello');
|
||||
socket.resume();
|
||||
socket.destroy();
|
||||
});
|
||||
|
||||
socket.once('close', function() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user