Skip to content

Commit 79c1ba1

Browse files
committed
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: nodejs/node-v0.x-archive#8780 Fix: nodejs#1696
1 parent e329020 commit 79c1ba1

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

lib/_tls_wrap.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,18 @@ TLSSocket.prototype._wrapHandle = function(handle) {
305305
});
306306

307307
this.on('close', function() {
308-
this._destroySSL();
308+
// Make sure we are not doing it on OpenSSL's stack
309+
setImmediate(destroySSL, this);
309310
res = null;
310311
});
311312

312313
return res;
313314
};
314315

316+
function destroySSL(self) {
317+
self._destroySSL();
318+
}
319+
315320
TLSSocket.prototype._destroySSL = function _destroySSL() {
316321
if (!this.ssl) return;
317322
this.ssl.destroySSL();

src/tls_wrap.cc

+13
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ void TLSWrap::EncOutCb(WriteWrap* req_wrap, int status) {
337337
return;
338338
}
339339

340+
if (wrap->ssl_ == nullptr)
341+
return;
342+
340343
// Commit
341344
NodeBIO::FromBIO(wrap->enc_out_)->Read(nullptr, wrap->write_size_);
342345

@@ -547,6 +550,7 @@ int TLSWrap::DoWrite(WriteWrap* w,
547550
size_t count,
548551
uv_stream_t* send_handle) {
549552
CHECK_EQ(send_handle, nullptr);
553+
CHECK_NE(ssl_, nullptr);
550554

551555
bool empty = true;
552556

@@ -620,6 +624,11 @@ void TLSWrap::OnAfterWriteImpl(WriteWrap* w, void* ctx) {
620624
void TLSWrap::OnAllocImpl(size_t suggested_size, uv_buf_t* buf, void* ctx) {
621625
TLSWrap* wrap = static_cast<TLSWrap*>(ctx);
622626

627+
if (wrap->ssl_ == nullptr) {
628+
*buf = uv_buf_init(nullptr, 0);
629+
return;
630+
}
631+
623632
size_t size = 0;
624633
buf->base = NodeBIO::FromBIO(wrap->enc_in_)->PeekWritable(&size);
625634
buf->len = size;
@@ -740,6 +749,10 @@ void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
740749
void TLSWrap::EnableSessionCallbacks(
741750
const FunctionCallbackInfo<Value>& args) {
742751
TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
752+
if (wrap->ssl_ == nullptr) {
753+
return wrap->env()->ThrowTypeError(
754+
"EnableSessionCallbacks after destroySSL");
755+
}
743756
wrap->enable_session_callbacks();
744757
NodeBIO::FromBIO(wrap->enc_in_)->set_initial(kMaxHelloLength);
745758
wrap->hello_parser_.Start(SSLWrap<TLSWrap>::OnClientHello,

0 commit comments

Comments
 (0)