diff options
author | Anatoli Papirovski <apapirovski@mac.com> | 2018-06-05 20:34:47 -0400 |
---|---|---|
committer | Anatoli Papirovski <apapirovski@mac.com> | 2018-06-11 09:36:00 -0700 |
commit | 083139d440f9e06e7d1f0eff331886117b5165a8 (patch) | |
tree | 92ce29c3b6287fd9be04af7a01334243b9d3fd36 /src | |
parent | f86a181d471099417828ffd787aa6b3e0356ac36 (diff) | |
download | android-node-v8-083139d440f9e06e7d1f0eff331886117b5165a8.tar.gz android-node-v8-083139d440f9e06e7d1f0eff331886117b5165a8.tar.bz2 android-node-v8-083139d440f9e06e7d1f0eff331886117b5165a8.zip |
http2: safer Http2Session destructor
It's hypothetically (and with certain V8 flags) possible for the session
to be garbage collected before all the streams are. In that case, trying
to remove the stream from the session will lead to a segfault due to
attempting to access no longer valid memory. Fix this by unsetting the
session on any streams still around when destroying.
PR-URL: https://github.com/nodejs/node/pull/21194
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/node_http2.cc | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/node_http2.cc b/src/node_http2.cc index 5629298eb9..a419067923 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -499,6 +499,8 @@ Http2Session::Http2Session(Environment* env, Http2Session::~Http2Session() { CHECK_EQ(flags_ & SESSION_STATE_HAS_SCOPE, 0); Debug(this, "freeing nghttp2 session"); + for (const auto& stream : streams_) + stream.second->session_ = nullptr; nghttp2_session_del(session_); } @@ -1706,11 +1708,11 @@ Http2Stream::Http2Stream( Http2Stream::~Http2Stream() { + if (session_ == nullptr) + return; Debug(this, "tearing down stream"); - if (session_ != nullptr) { - session_->RemoveStream(this); - session_ = nullptr; - } + session_->RemoveStream(this); + session_ = nullptr; } std::string Http2Stream::diagnostic_name() const { @@ -1785,7 +1787,8 @@ void Http2Stream::Destroy() { // We can destroy the stream now if there are no writes for it // already on the socket. Otherwise, we'll wait for the garbage collector // to take care of cleaning up. - if (!stream->session()->HasWritesOnSocketForStream(stream)) + if (stream->session() == nullptr || + !stream->session()->HasWritesOnSocketForStream(stream)) delete stream; }, this, this->object()); |