diff options
author | James M Snell <jasnell@gmail.com> | 2020-11-12 23:34:33 +0300 |
---|---|---|
committer | Beth Griggs <bgriggs@redhat.com> | 2021-01-04 20:10:40 +0300 |
commit | b0ac080fa77286dbc92b0beb49d1bb4d69c5784e (patch) | |
tree | 1a9a91fc71c4f5b2f66406d4e9bff70dde80d151 /src/stream_base-inl.h | |
parent | 029703100fb33a13a94e32c06d7677ec33801dcc (diff) |
src: retain pointers to WriteWrap/ShutdownWrap
Avoids potential use-after-free when wrap req's are synchronously
destroyed.
CVE-ID: CVE-2020-8265
Fixes: https://github.com/nodejs-private/node-private/issues/227
Refs: https://hackerone.com/bugs?subject=nodejs&report_id=988103
PR-URL: https://github.com/nodejs-private/node-private/pull/23
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'src/stream_base-inl.h')
-rw-r--r-- | src/stream_base-inl.h | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h index c003ffc1ef6..c1590cc957e 100644 --- a/src/stream_base-inl.h +++ b/src/stream_base-inl.h @@ -137,8 +137,11 @@ int StreamBase::Shutdown(v8::Local<v8::Object> req_wrap_obj) { StreamReq::ResetObject(req_wrap_obj); } + BaseObjectPtr<AsyncWrap> req_wrap_ptr; AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(GetAsyncWrap()); ShutdownWrap* req_wrap = CreateShutdownWrap(req_wrap_obj); + if (req_wrap != nullptr) + req_wrap_ptr.reset(req_wrap->GetAsyncWrap()); int err = DoShutdown(req_wrap); if (err != 0 && req_wrap != nullptr) { @@ -172,7 +175,7 @@ StreamWriteResult StreamBase::Write( if (send_handle == nullptr) { err = DoTryWrite(&bufs, &count); if (err != 0 || count == 0) { - return StreamWriteResult { false, err, nullptr, total_bytes }; + return StreamWriteResult { false, err, nullptr, total_bytes, {} }; } } @@ -182,13 +185,14 @@ StreamWriteResult StreamBase::Write( if (!env->write_wrap_template() ->NewInstance(env->context()) .ToLocal(&req_wrap_obj)) { - return StreamWriteResult { false, UV_EBUSY, nullptr, 0 }; + return StreamWriteResult { false, UV_EBUSY, nullptr, 0, {} }; } StreamReq::ResetObject(req_wrap_obj); } AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(GetAsyncWrap()); WriteWrap* req_wrap = CreateWriteWrap(req_wrap_obj); + BaseObjectPtr<AsyncWrap> req_wrap_ptr(req_wrap->GetAsyncWrap()); err = DoWrite(req_wrap, bufs, count, send_handle); bool async = err == 0; @@ -206,7 +210,8 @@ StreamWriteResult StreamBase::Write( ClearError(); } - return StreamWriteResult { async, err, req_wrap, total_bytes }; + return StreamWriteResult { + async, err, req_wrap, total_bytes, std::move(req_wrap_ptr) }; } template <typename OtherBase> |