tls: use after free in tls_wrap · nodejs/node@743f890

@@ -298,10 +298,12 @@ void TLSWrap::EncOut() {

298298299299300300

void TLSWrap::OnStreamAfterWrite(WriteWrap* req_wrap, int status) {

301-

// Report back to the previous listener as well. This is only needed for the

302-

// "empty" writes that are passed through directly to the underlying stream.

303-

if (req_wrap != nullptr)

304-

previous_listener_->OnStreamAfterWrite(req_wrap, status);

301+

if (current_empty_write_ != nullptr) {

302+

WriteWrap* finishing = current_empty_write_;

303+

current_empty_write_ = nullptr;

304+

finishing->Done(status);

305+

return;

306+

}

305307306308

if (ssl_ == nullptr)

307309

status = UV_ECANCELED;

@@ -567,18 +569,17 @@ int TLSWrap::DoWrite(WriteWrap* w,

567569

// However, if there is any data that should be written to the socket,

568570

// the callback should not be invoked immediately

569571

if (BIO_pending(enc_out_) == 0) {

570-

// We destroy the current WriteWrap* object and create a new one that

571-

// matches the underlying stream, rather than the TLSWrap itself.

572-573-

// Note: We cannot simply use w->object() because of the "optimized"

574-

// way in which we read persistent handles; the JS object itself might be

575-

// destroyed by w->Dispose(), and the Local<Object> we have is not a

576-

// "real" handle in the sense the V8 is aware of its existence.

577-

Local<Object> req_wrap_obj =

578-

w->GetAsyncWrap()->persistent().Get(env()->isolate());

579-

w->Dispose();

580-

w = underlying_stream()->CreateWriteWrap(req_wrap_obj);

581-

return stream_->DoWrite(w, bufs, count, send_handle);

572+

CHECK_EQ(current_empty_write_, nullptr);

573+

current_empty_write_ = w;

574+

StreamWriteResult res =

575+

underlying_stream()->Write(bufs, count, send_handle);

576+

if (!res.async) {

577+

env()->SetImmediate([](Environment* env, void* data) {

578+

TLSWrap* self = static_cast<TLSWrap*>(data);

579+

self->OnStreamAfterWrite(self->current_empty_write_, 0);

580+

}, this, object());

581+

}

582+

return 0;

582583

}

583584

}

584585