Skip to content

Commit a452546

Browse files
committed
Quic: fix Impl lifetime error
1 parent f4ae805 commit a452546

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

src/quic/session.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,12 @@ struct Session::Impl final : public MemoryRetainer {
540540
local_address_(config.local_address),
541541
remote_address_(config.remote_address),
542542
application_(SelectApplication(session, config_)),
543-
timer_(session_->env(), [this] { session_->OnTimeout(); }) {
543+
timer_(session_->env(), [this] {
544+
auto impl = session_->impl_; // we hold a reference to ourself,
545+
// as the reference from session to us may go away
546+
// while we call OnTimeout
547+
session_->OnTimeout();
548+
}) {
544549
timer_.Unref();
545550
}
546551
DISALLOW_COPY_AND_MOVE(Impl)
@@ -556,11 +561,16 @@ struct Session::Impl final : public MemoryRetainer {
556561
state_->closing = 1;
557562
STAT_RECORD_TIMESTAMP(Stats, closing_at);
558563

564+
// we hold a reference to ourself,
565+
// as the reference from session to us may go away
566+
// while we destroy streams
567+
auto impl = session_->impl_;
568+
559569
// Iterate through all of the known streams and close them. The streams
560570
// will remove themselves from the Session as soon as they are closed.
561571
// Note: we create a copy because the streams will remove themselves
562572
// while they are cleaning up which will invalidate the iterator.
563-
StreamsMap streams = streams_; // needs to be a ref
573+
StreamsMap streams = streams_;
564574
for (auto& stream : streams) stream.second->Destroy(last_error_);
565575
DCHECK(streams_.empty()); // do not check our local copy
566576

@@ -1295,7 +1305,7 @@ Session::Session(Endpoint* endpoint,
12951305
: AsyncWrap(endpoint->env(), object, PROVIDER_QUIC_SESSION),
12961306
side_(config.side),
12971307
allocator_(BindingData::Get(env())),
1298-
impl_(std::make_unique<Impl>(this, endpoint, config)),
1308+
impl_(std::make_shared<Impl>(this, endpoint, config)),
12991309
connection_(InitConnection()),
13001310
tls_session_(tls_context->NewSession(this, session_ticket)) {
13011311
DCHECK(impl_);

src/quic/session.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,9 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source {
497497

498498
Side side_;
499499
ngtcp2_mem allocator_;
500-
std::unique_ptr<Impl> impl_;
500+
std::shared_ptr<Impl> impl_; // we need to have a shared ptr, there are situations
501+
// where Impl calls the session and the session resets this pointer to Impl,
502+
// in this case we need to hold a local shared ptr to prevent use after free
501503
QuicConnectionPointer connection_;
502504
std::unique_ptr<TLSSession> tls_session_;
503505
BaseObjectPtr<LogStream> qlog_stream_;

0 commit comments

Comments
 (0)